博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python3简单爬虫
阅读量:6280 次
发布时间:2019-06-22

本文共 2454 字,大约阅读时间需要 8 分钟。

hot3.png

    刚接触爬虫,由于本科主要是学java的,因此之前从java入手爬虫。其实就是模拟http请求,然后将返回的html代码提取自己想要的数据。不过说起来很简单,作为小白,实现起来还是不容易阿。

    之前稍微看了下一个java的框架源代码(还没全部看完,不过和还是会抽时间看看的),不过导师让我用python实现,因而转入python(导师很喜欢python的样子阿)。

    说起python的环境搭建等等,我作为刚入python的小白其实还不清楚,直接下载了一个python3的源码,然后,照着操作安装了下,其实很简单,不多说了。

    爬网页第一步就是要获取html代码

        说来python获取html十分简单,只要几行就可以了,把我给震惊到了!!像java还是要写不少行的,再加上异常,代码看着还是挺臃肿的(不过习惯了)。

#coding=utf-8import urllib.requestdef getHtml(url):    response= urllib.request.urlopen(url)    html = response.read()    return htmlhtml = getHtml("http://www.baidu.com")print(html)

       这里爬取了百度首页的html代码,没错,这是这么简单。

        这里用了一个urllib.request模块,其实我觉得把java代码封装下,写起来也没几行(纯属小白看法)。

        试过了baidu之后想爬取下大众点评的首页,出现了403 forbid错误,一番查询后发现时缺少User-Agent,因此换一种方式,先创建一个request对象,然后将其加入头部即可:

request=urllib.request.Request(url)request.add_header("User-Agent","xxx")response=urllib.request.urlopen(request)html=response.read()print(html)

        就是这么简单!

        但还有编码的问题,返回的数据并没有解码,只要html.decode("utf-8")就可以了,具体的编码格式参照该网页的charset

不过也可以用chardet来检测该网页是什么编码,chardet模块需要下载,在命令行输入pip install chardet 即可。

import chardetcharset = chardet.detect(html)if(charset['encoding'] != None):    html = html.decode(charset['encoding'])    return html

         上述代码的html就是之前获取到的html,然后用chardet检测下,获取其中的encoding编码,用这个编码解码即可。

        

          最后这个差点让我崩溃,哎,不得不吐糟,这个问题困扰了我整整一天,研究了很长时间,毕竟小白啊,很多东西还要学。这个问题就是用p3的这个获取html其实是字节而非字符串(这也是上面要用decode解码的原因),但是问题是这个字节可能是压缩过的。

        这个问题是怎么来的呢,是在我爬取 这个页面的时候出现的错误,返回的是这样一串东西b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xd5}iw\x1b\xc7\x95......    然后我还异想天开的用上述方法解码,然后悲剧了UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte,我的天,然后我就一直在研究解码的问题了~~~~~,可是关键不在于解码啊,所以苦苦得不到结果。实在没办法,只能请大师兄帮我一起研究下什么个情况。

        后来我们发现,爬取这个有时候能成功,有时候失败,这就很奇怪,这是什么个情况!!!!没办法,用Fiddler工具看下吧(正好之前下了这个抓包工具,很强大!!)然后来了一组同一网站有成功有失败的请求,仔细观察它们到底有啥差别,然后惊讶的发现,失败的那个响应头(应该是响应头里的吧)里多了个 Content-Encoding: gzip,尼玛!!!学linux,正好知道这个gzip,这不是压缩的一个命令么!!!难怪失败的response body应该要有3w多字节,实际只有1w多了。

        既然已经有了方向,自然要看看到底是不是这个Content-Encoding: gzip在作怪了,这时候就要解压缩啊,百度后有了结果,由于这是字节的压缩,因此需要用到BytesIO和gzip,注意py3里BytesIO已经移到了io包里了(又百度半天)

from io import BytesIOimport gzip#这里省略获取response的代码if(response.headers.get('Content-Encoding')=='gzip'):    compresseddata = response.read()    # gzip解压缩    compressedstream = BytesIO(compresseddata)    gzipper = gzip.GzipFile(fileobj=compressedstream)    html = gzipper.read()    #解压缩完成    html = html.decode("UTF-8")#这里才是根据网页charset解码问题    print(html)

        困扰了一天的问题总算解决了,哎,作为小白也是不容易啊!!还是要感谢下大师兄陪我一起折腾啊!!!希望能帮助到一些人,也以便我未来查阅。

        

转载于:https://my.oschina.net/lvjianjian/blog/667252

你可能感兴趣的文章
LINUX家族神器-Gentoo安装部署
查看>>
产品设计体会(6024)一个产品经理小站的访客分析
查看>>
Web服务器的配置与管理(4) 配置访问权限和安全
查看>>
Vmware导致VS2005调试自动退出的问题解决方案
查看>>
Linux中设置Tomcat开机自启动
查看>>
类方法
查看>>
ExtJs中column与form布局的再次领悟
查看>>
asp.net MVC2 初探十一
查看>>
C++/CLI思辨录之Object的对象布局
查看>>
Windows 7优化调整使用小技巧
查看>>
使用 “Unicode 字符集 ” 使用错误,应该使用 “使用多字节字符集”
查看>>
C中如何实现C++中的默认参数?
查看>>
某直播App问题分析
查看>>
InnoDB引擎的索引和存储结构
查看>>
Selenium私房菜系列8 -- 玩转Selenium Server
查看>>
重学自动控制 PID
查看>>
游戏演示(包含源码)[名称待定]
查看>>
浅析SQL Server实现分布式事务的两阶段提交协议2PC
查看>>
IBM WebSphere 产品介绍
查看>>
结构型模式之Adapter模式
查看>>