如何轻松爬取网页数据?

2017-06-15   出处: 腾讯移动品质中心TMQ  作/译者: cassieyang  

一、引言

在实际工作中,难免会遇到从网页爬取数据信息的需求,如:从微软官网上爬取最新发布的系统版本。很明显这是个网页爬虫的工作,所谓网页爬虫,就是需要模拟浏览器,向网络服务器发送请求以便将网络资源从网络流中读取出来,保存到本地,并对这些信息做些简单提取,将我们要的信息分离提取出来。

在做网页爬虫工作时会发现并不是所有网站都是一样,比如有些网址就是一个静态页面、有些需要登录后才能获取到关键信息等等。此外,python简单而又强大,又有不少第三方库可以让我们轻松拿到浏览器中所看到的内容。因而,本文将根据网站特性进行分类介绍几种使用python完成网页爬虫的方法。


二、静态页面


在做爬虫工作时,什么类型的网站最容易爬取数据信息呢?不需要登录等处理,直接用Get方法请求URL即可从服务器获取到返回数据,如我们访问一些博客文章,一个Get请求就可以拿到博客文章里的内容。下面将举例介绍如何爬虫这种类型页面内容该如何爬取。

示例

1、需求说明:假设我们需要及时感知到电脑管家官网上相关产品下载链接的变更,这就要求我们写个自动化程序从官网上爬取到电脑管家的下载链接。

2、分析过程:在浏览器中打开https://guanjia.qq.com,按下F12, 查看网络请求,内容如下图。这里只有一个Get请求,没有登录,也不涉及加密过程。此外,点击Elements,可以很容易的从源码中找到下载链接。


3、解决方案: requests是python的第三方库,可以发送网络请求数据并获取服务器返回的源码。使用requests库获取到html文件,然后利用正则等字符串解析手段或者BeautifulSoup库(第三方库)完成信息提取。下面代码展示的是利用requests库和BeautifulSoup库完成信息提取。



知识点

1、有些网络服务器反感爬虫,会对请求头做个简单判别,直接拒绝那些明显是由自动化程序发起的请求。就例如图2中的代码,python使用的默认请求头User-Agent值为Python-urllib/3.4,而浏览器访问时User-Agent值为:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.3。为了避免自动化程序被拒绝,在请求时可以修改请求头,让自动化程序更像一个浏览器。


2、在网页爬取时,可能会遇到公司网络不允许访问外网的情况,这时就需要设置代理IP: requests.get("https://guanjia.qq.com", proxies={“http”:“127.0.0.1:8087”})

3、BeautifulSoupHTML/XML解析器,它可以很好的处理不规范标记并生成剖析树,通常用来分析爬虫抓取的web文档,可以大大节省编程时间。


三、POST表单


前面介绍的是通过HTTP协议的Get方法去请求信息,对应网站不涉及post表单。表单是含有<form>标签,是要交互的数据区域,你可能需要输入文字、做下拉选择等,完成与服务器的交互。下面将给个简单的示例让大家理解post表单情况。

示例

1、需求说明:访问网址,并输出服务器返回内容。

2、分析过程:在浏览器中打开http://pythonscraping.com/pages/cookies/welcome.php,展示在面前的是个登录界面, 按下F12,可看到如下图的信息。很明显这是一个表单。点击登录后查看Network,会发现看到一个post请求以及请求参数。当登录完成后,即可访问http://pythonscraping.com/pages/cookies/profile.php,查看网址中详细内容。


3、解决方案:仍然使用强大的requests库完成post表单操作,下面将仅展示post登录那里,登录过后的页面内容解析和第二部分一致,这里不再详细赘述。


知识点

1、需要注意cookie的追踪。一旦网站验证了你的登录权证,它将会将登陆权证保存在浏览器的cookie中,若是我们一直自己处理cookie的追踪,在面对复杂网址时将会比较麻烦,降低开发效率。我们可以使用Session对象解决这个问题,就如上述截图代码中。Session会持续跟踪会话信息,包括cookieheader。可以调用session.cookie.get_dict()查看当前session cookie值。

2、在表单中存在“隐含”字段,该字段是对浏览器可见,但是对用户不可见。一般而言,“隐含”字段是在每次Get请求时生成,每次打开同个网址,同个“隐含”值不一样。这个处理有一定的反爬虫效果。至于“隐含”字段是否作为post参数,可以手动在浏览器下完成表单请求,观察请求参数是否包含某个“隐含”参数。如下图:网址包含“隐含”字段,并在post时带上。


第二部分介绍的header、代理IP同样适用于这里。


四、HTTP基本接入认证


基本认证是一种用来允许Web浏览器后者其他客户端程序在请求时,提供用户名和口令形式的身份凭证的一种登录验证方式。把“用户名+冒号+密码”用BASE64算法加密后的字符串放到httprequest中的headerAuthorization中发送给服务端。在发明cookie之前,HTTP基本认证是处理网站登录最常用的方法,目前一些安全性比较高网址还在使用这种方式。

示例

1、需求说明:访问某网站(涉及内部,不对外公布)。

2、分析过程:在浏览器中输入该网址,看到如下页面。这时候需要输入用户名和密码才能得到所需要的数据。否则会返回错误代码401,要求用户重新提供用户名和密码。此外用fiddle抓取中间数据时,header中有如下信息:,很明显这是一个HTTP基本认证。


3、解决方案:这个实际是个post请求,和普通post的请求区别是:在每次请求数据时,需要用BASE64加密用户名和密码,并附加到请求头中。requests库提供了一个auth模块专门用于处理HTTP认证,这样就不用程序自己做加密处理。下面给出具体代码:


知识点

目前有多种http登录验证方法,其中最广泛应用的是基本验证和摘要验证,auth模块也提供摘要验证处理方法,具体使用方法我也没有研究过,请各位查询相关资料。


五、JavaScript动态页面


前面介绍了静态页面和含有post表单网站的爬虫方式,相对比较简单。而实际在做网页爬虫工作时页面情况更加多样复杂。如:

1、网页中包含javascript代码,需要经过渲染处理才能获取原始数据;

2、网站具有一定反爬虫能力,有些cookie是需要客户端脚本执行JS后才会产生,而requests模块又不能执行JS代码,如果我们按照第三部分操作来post表单,会发现部分少了部分cookie,导致请求被拒绝。在当前知名网站反爬虫工作做的比较好,很难找到简单post表单就可以。

那有什么好的方式解决这种类型网站的爬虫呢?

“python+ selenium + 第三方浏览器“。

示例

1、需求说明:登录微软官网https://connect.microsoft.com/site1304/Downloads,自动下载微软最近发布iso文件。

2、分析过程

(1) 当我们使用python request库去获取服务器源码时,发现python获取的源码和浏览器上渲染出的场景不一样,Python拿到是JS源码。如下图:

Python有个第三方库PyV8,该库可以执行JS代码,但执行效率低,此外微软官网还涉及JS加密的Cookie,若是采用requests + Pyv8 + BeautifulSoup 三种库组合方式处理,那代码会显得臃肿杂乱。

那是否有其他更为简洁易懂的方式呢?

有, selenium。

(2)“Selenium+ 第三方浏览器”,可以让浏览器自动加载页面,由浏览器执行JS从而获取到需要的数据,这样我们的python代码就无需实现浏览器客户端的功能。可以说,“Selenium + 第三方浏览器”组成了一个强大的网络爬虫,可以处理cookie、javascript等页面爬取情况。第三方浏览器分有界面(chrome)和无界面(PhantomJS),有界面浏览器就是可以直接看到浏览器被打开以及跳转的过程。无界面浏览器会将网站加载到内存并执行页面上的JS,不会有图形界面。可以自己喜好或者需求选择第三方浏览器。

3、解决方案:采用“selenium+ chrome”方式完成需求。

(1)下载安装python的selenium库;

(2)下载chromeDriver到本地;

(3)利用webdriver api完成对页面的操作。下面给出一个示例,完成微软官网的登录。示例代码在初始化webdriver时设置了网络代理、指定了浏览器下载文件保存路径、让chrome提示下载进度等信息。


知识点

在实例化webdriver时,可以通过参数对浏览器做些设置,如设置网络代理、浏览器下载文件保存路径等。若是不传参数,则默认继承本地浏览器设置。若是对浏览器启动时属性进行设置,则就利用到了ChromeOption类。具体信息可参考chromedriver官网

python + selenium + 第三方浏览器”可以处理多种爬虫场景,包括静态页面,post表单,以及JS等。应用场景很强大,使用selenium操作浏览器进行模拟点击的方式就可以让我们省心很多,不需要担心有什么“隐藏字段”、cookie追踪等。但对于包含验证码网页的操作,这种方式也不好处理,主要困难在于图像识别。


六、总结


本文主要针对各网站特点给出不同的爬虫方式,可以应对大量场景的数据爬取。在实际工作中使用频率最多还是“静态页面“javascript动态页面这两种。当然,若是页面包含验证码,那就需要结合图像识别工具做些事情了,这种情况相对也比较难处理,图像识别准确率受到图片内容影响。

这里是个人的一些小总结,不知道大家是否有其他更好的方法呢?

大家若是有其他比较好的爬虫案例,欢迎在评论区留言,大家一起学习交流!







欢迎给测试窝投稿或参与内容翻译工作,请邮件至editors@testwo.com。也欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,并与我们的编辑和其他窝友交流。
221°|2213 人阅读|0 条评论

登录 后发表评论