简单介绍一下爬虫原理。并给出 51job网站完整的爬虫方案。
爬虫基础知识
数据来源
网络爬虫的数据一般都来自服务器的响应结果,通常有html和json数据等,这两种数据也是网络爬虫的主要数据来源。
其中html数据是网页的源代码,通过浏览器-查看源代码可以直接查看,例如:
json是一种数据存储格式,往往包含了最原始的数据内容,一般不直接显示在网页中,这里可以通过Chrome浏览器>开发者工具中的Network选项捕获到服务器返回的json数据,例如:
数据请求
数据请求的方式一般有两种:GET方法和POST方法。也可以通过Chrome浏览器来捕获访问一个浏览器时的所有请求。这里以简书主页为例,打开Chrome浏览器-开发者工具(F12),切换到Network选项,在地址栏输入http://www.jianshu.com/, 选择XHR类型,可以看到一条请求的内容,打开Headers,在General中可以看到请求方式为GET方式,
其中的Request Headers便是访问这个网页时的请求数据,如下图。
这个Headers可以用Python中的字典来表示,包含了用户请求的一些信息,例如编码、语言、用户登陆信息、浏览器信息等。
下面还有一个Query String Parameters,这里面包含了用户请求的一些参数,也是请求数据的一部分。
利用requests库请求数据
利用Python构建数据请求的方式有很多,在python3中,主要有urllib和requests两个类库可以实现该功能。urllib是官方标准库,其官方文档传送门。这里主要介绍第三方库requests,它是基于urllib编写的,比urllib用起来更加便捷,可以节约时间。
requests安装方法:
1 | $ pip install requests |
利用requests构建数据请求主要方式:
1 | import requests |
或者
1 | import requests |
其中,get()与post()中都可以添加headers、params等参数,以字典的形式传递即可。一般来说,简单的网页通过传入url数据即可成功请求数据。不过一些网站采用了反爬虫机制,需要传入headers及params等参数,以模拟浏览器访问、用户登陆等行为,才可以正常请求数据。
利用webdriver请求数据
webdriver是一个用来进行复杂重复的web自动化测试的工具,能够使用chrome、firefox、IE浏览器进行web测试,可以模拟用户点击链接,填写表单,点击按钮等。因此,相对于requests库来说,webdriver在模拟浏览器鼠标点击滑动等事件上有着天然的优势,并且真实模拟了浏览器的操作,不易被反爬虫机制发现,因此是一个很好用的爬虫工具。当然,其缺点在于速度较慢,效率不高。
webdriver安装:
1 | $ pip install selenium |
除了安装selnium库,webdriver的运行还需要进行浏览器驱动的配置。Chrome、火狐和IE浏览器都有其配置方式,具体方法查看 链接。
这里以IE浏览器为例,做一个简单的示范:
1 | from selenium import webdriver |
如此,IE浏览器配置完毕,其中”IEDriverServer.exe”是IE浏览器驱动的存储路径。
于是,访问简书网主页数据只需要一步:
1 | driver.get(http://www.jianshu.com/) |
数据解析
使用requests请求下来的数据,可以利用.text()方法或者.content()方法访问,对于文本请求,二者并无太大差别,主要在于编码问题。具体用法可以参考官方文档,这里不再赘述。使用webdriver请求下来的数据可以用.page_source属性获取。请求下来的数据一般包含了大量的网页源代码,如何将其解析以提取出想要的内容?
html类型数据解析
html语言即超文本标记语言,它是由一个个html标签构成的,是结构化的语言,因此很容易从中匹配提取信息。这种类型的数据解析的方法有很多,比如利用正则表达式,按照html标签的结构进行字符串匹配,或则利用lxml库中的xpath方法使用xpath路径定位到每一个节点、也有类似jQuery的PyQuery方法。这里主要介绍BeautifulSoup方法。
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间。该介绍来源于其官方中文文档,传送门。利用BeautifulSoup能够将html字符串转化为树状结构,并非常快速地定位到每一个标签。
目前版本是BeautifulSoup4,pip安装方法:
1 | $ pip install BeautifulSoup4 |
或者,下载bs4的源码,然后解压并运行:
1 | $ python setup.py install |
利用BeautifulSoup解析html数据的关键步骤为:
1 | from bs4 import BeautifulSoup |
如果采用webdriver请求数据,那么:
1 | from bs4 import BeautifulSoup |
如此,便将html数据转换成BeautifulSoup中的树状结构。然后利用BeautifulSoup中的find()、find_all()等方法即可定位到每一个节点。详情请参阅 官方文档。
json类型数据解析
json类型的数据已经是高度结构化的数据,跟Python中字典的表示形式一样,因此在解析上十分方便。可以通过:
1 | import json |
直接读取json数据,且能够返回字典类型。
大数据职位数据爬虫实战
这里以51job网站为例,构建大数据相关职位的数据爬虫。其中搜索关键词为:
1 | 数据科学家 |
网页分析
打开51job首页http://www.51job.com/, 在搜索框中输入“数据科学家”,将搜索框中的地区点开,去掉当前勾选的城市,即默认在全国范围搜索。点击“搜索”按钮,得到搜索结果。这时将网址栏URL复制出来:
1 | http://search.51job.com/list/000000,000000,0000,00,9,99, |
结果不止一页,点击第二页,同样将URL复制出来:
1 | http://search.51job.com/list/000000,000000,0000,00,9,99, |
很容易发现,这两段url唯一的不同在于”.html”前面的数字1和2,因此它代表了页码。其中:
1 | %25E6%2595%25B0%25E6%258D%25AE%25E7%25A7%2591%25E5%25AD%25A6%25E5%25AE%25B6 |
是一种URL编码,翻译成中文就是“数据科学家”,转换方式可以使用urllib库中的quote()方法:
1 | import urllib.quote |
可以通过第一次的搜索结果获取页码数:
1 | def GetPages(keyword): |
由此,便可实现针对特定关键词的所有搜索结果的页面的遍历。
URL列表构建
打开搜索结果页面,会发现,点击职位名称可以链接到每个职位的详情页面,也正是所需要的数据源。因此,只需要获取所有的搜索结果中的职位名称的超链接地址,便可以遍历所有职位的详细数据:
1 | def GetUrls(keyword, page_num): |
构造数据请求
在获取了所有的职位数据的url之后,使用requests访问这些url发现,并不能顺利获取数据。因此,可以考虑在请求中加入headers数据,其中包含cookie和User_Agent:
1 | User_Agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36' |
这样,可以成功请求每个职位的详情页面数据:
数据解析
数据解析首先是明确数据需求,这里将数据尽可能多的抓取下来。
以职位要求一栏为例,通过访问多个页面对比发现,这一栏可能显示的要求个数不一样:
这里包括了经验、学历、招聘人数和发布时间
而这里则没有对于经验的要求。
利用浏览器开发者选项功能,查看这一栏的源码:
这里职位的要求都放在一个class=”sp4”的span中,通过查找功能可以发现没有其他的class=”sp4”的标签,所以利用find_all()方法可以轻松定位到这些职位要求数据。
通过比较可以发现这最多的要求个数为4,所以在个数不确定的情况下,可以先新建一个包含四个空字符串元素的新数组,将所有的要求个数填入该数组,这样可以保证不同网页的数据都能获取完整。
1 | spans = soup.find_all('span', class_='sp4') |
完整代码如下:
1 | # -*- coding: utf-8 -*- |