Python爬⾍抓取⼤数据岗位招聘信息(51job为例)简单介绍⼀下爬⾍原理。并给出 完整的爬⾍⽅案。
爬⾍基础知识
数据来源
⽹络爬⾍的数据⼀般都来⾃服务器的响应结果,通常有html和json数据等,这两种数据也是⽹络爬⾍的主要数据来源。
其中html数据是⽹页的源代码,通过浏览器-查看源代码可以直接查看,例如:
json是⼀种数据存储格式,往往包含了最原始的数据内容,⼀般不直接显⽰在⽹页中,这⾥可以通过Chrome浏览器>开发者⼯具中的Network选项捕获到服务器返回的json数据,例如:
数据请求
这个Headers可以⽤Python中的字典来表⽰,包含了⽤户请求的⼀些信息,例如编码、语⾔、⽤户登陆信息、浏览器信息等。
下⾯还有⼀个Query String Parameters,这⾥⾯包含了⽤户请求的⼀些参数,也是请求数据的⼀部分。
利⽤requests库请求数据
利⽤Python构建数据请求的⽅式有很多,在python3中,主要有urllib和requests两个类库可以实现该功能。urllib是官⽅标准库,其官⽅⽂档。这⾥主要介绍第三⽅库requests,它是基于urllib编写的,⽐urllib⽤起来更加便捷,可以节约时间。
requests安装⽅法:
$  pip install requests
利⽤requests构建数据请求主要⽅式:
import requests
req = (url)
或者
import requests
req = requests.post(url)
其中,get()与post()中都可以添加headers、params等参数,以字典的形式传递即可。⼀般来说,简单的⽹页通过传⼊url数据即可成功请求数据。不过⼀些⽹站采⽤了反爬⾍机制,需要传⼊headers及params等参数,以模拟浏览器访问、⽤户登陆等⾏为,才可以正常请求数据。
利⽤webdriver请求数据
webdriver是⼀个⽤来进⾏复杂重复的web⾃动化测试的⼯具,能够使⽤chrome、firefox、IE浏览器进⾏web测试,可以模拟⽤户点击链接,填写表单,点击按钮等。因此,相对于requests库来说,webdriver在模拟浏览器⿏标点击滑动等事件上有着天然的优势,并且真实模拟了浏览器的操作,不易被反爬⾍机制发现,因此是⼀个很好⽤的爬⾍⼯具。当然,其缺点在于速度较慢,效率不⾼。
webdriver安装:
$ pip install selnium
除了安装selnium库,webdriver的运⾏还需要进⾏浏览器驱动的配置。Chrome、⽕狐和IE浏览器都有其配置⽅式,具体⽅法查看 。
这⾥以IE浏览器为例,做⼀个简单的⽰范:
from selenium import webdriver
import os
iedriver =""
driver = webdriver.Ie(iedriver)
如此,IE浏览器配置完毕,其中""是IE浏览器驱动的存储路径。
于是,访问简书⽹主页数据只需要⼀步:
<(www.jianshu/)
数据解析
使⽤requests请求下来的数据,可以利⽤.text()⽅法或者.content()⽅法访问,对于⽂本请求,⼆者并⽆太⼤差别,主要在于编码问题。具体⽤法可以参考官⽅⽂档,这⾥不再赘述。使⽤webdriver请求下来的数据可以⽤.page_source属性获取。请求下来的数据⼀般包含了⼤量的⽹页源代码,如何将其解析以提取出想要的内容?
html类型数据解析
html语⾔即超⽂本标记语⾔,它是由⼀个个html标签构成的,是结构化的语⾔,因此很容易从中匹配提取信息。这种类型的数据解析的⽅法有很多,⽐如利⽤正则表达式,按照html标签的结构进⾏字符串匹配,或则利⽤lxml库中的xpath⽅法使⽤xpath路径定位到每⼀个节点、也有类似jQuery的PyQuery⽅法。这⾥主要介绍BeautifulSoup⽅法。
是⼀个可以从HTML或XML⽂件中提取数据的Python库.它能够通过你喜欢的转换器实现惯⽤的⽂档导航,查,修改⽂档的⽅式.Beautiful Soup会帮你节省数⼩时甚⾄数天的⼯作时间。该介绍来源于其官⽅中⽂⽂档,。利⽤BeautifulSoup能够将html字符串转化为树状结构,并⾮常快速地定位到每⼀个标签。
⽬前版本是BeautifulSoup4,pip安装⽅法:
$ pip install BeautifulSoup4
或者,下载bs4的,然后解压并运⾏:
$ python setup.py install
利⽤BeautifulSoup解析html数据的关键步骤为:
from bs4 import BeautifulSoup
soup = ts,"html.parser")
如果采⽤webdriver请求数据,那么:
from bs4 import BeautifulSoup
soup = BeautifulSoup(driver.page_source,"html.parser")
如此,便将html数据转换成BeautifulSoup中的树状结构。然后利⽤BeautifulSoup中的find()、find_all()等⽅法即可定位到每⼀个节点。详情请参阅 。
json类型数据解析
json类型的数据已经是⾼度结构化的数据,跟Python中字典的表⽰形式⼀样,因此在解析上⼗分⽅便。可以通过:
import json
data = json.)
直接读取json数据,且能够返回字典类型。
⼤数据职位数据爬⾍实战
这⾥以51job⽹站为例,构建⼤数据相关职位的数据爬⾍。其中搜索关键词为:
数据科学家
数据分析师51job人才招聘网
数据架构师
数据⼯程师
统计学家
数据库管理员
业务数据分析师
数据产品经理
⽹页分析
search.51job/list/000000,000000,0000,00,9,99,
%25E6%2595%25B0%25E6%258D%25AE%25E7%25A7%2591%25E5%25AD%25A6%25E5%25AE%25B6,
2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99°reefrom=99
&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0
&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=
结果不⽌⼀页,点击第⼆页,同样将URL复制出来:
search.51job/list/000000,000000,0000,00,9,99,
%25E6%2595%25B0%25E6%258D%25AE%25E7%25A7%2591%25E5%25AD%25A6%25E5%25AE%25B6,
2,2.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99
&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0
&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=
很容易发现,这两段url唯⼀的不同在于".html"前⾯的数字1和2,因此它代表了页码。其中:
%25E6%2595%25B0%25E6%258D%25AE%25E7%25A7%2591%25E5%25AD%25A6%25E5%25AE%25B6
是⼀种URL编码,翻译成中⽂就是“数据科学家”,转换⽅式可以使⽤urllib库中的quote()⽅法:
import urllib.quote
keyword ='数据科学家'
url = quote(keyword)
可以通过第⼀次的搜索结果获取页码数:
def GetPages(keyword):
keyword = quote(keyword, safe='/:?=')
url ='search.51job/jobsearch/search_result.php?fromJs=1&jobarea=000000%2C00&distric
t=000000&funtype=0000&industrytype=00&issueda te=9&providesalary=99&keyword='+keyword + \
'&keywordtype=2&curr_page=1&lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat= 0%2C0&radius=-1&ord_field=0&list_type=0&fromType=14&dibiaoid=0&confirmdate=9'
html = (url)
soup = t,"html.parser")
span = soup.find('div', class_='p_in').find('span', class_='td')
page_num = _text().replace('共','').replace('页,到第','')
return page_num
由此,便可实现针对特定关键词的所有搜索结果的页⾯的遍历。
URL列表构建
打开搜索结果页⾯,会发现,点击职位名称可以链接到每个职位的详情页⾯,也正是所需要的数据源。因此,只需要获取所有的搜索结果中的职位名称的超链接地址,便可以遍历所有职位的详细数据:
def GetUrls(keyword, page_num):
keyword = quote(keyword, safe='/:?=')
urls =[]
p = page_num+1
for i in range(1, p):
url ='search.51job/jobsearch/search_result.php?fromJs=1&jobarea=000000%2C00&district=000000&funtype=0000&industrytype=00&issue date=9&providesalary=99&keyword='+keyword + \
'&keywordtype=2&curr_page='+ \
str(i)+ \
'&lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_fiel d=0&list_type=0&dibiaoid=0&confirmdate=9'
html = (url)
soup = t,"html.parser")
ps = soup.find_all('p', class_='t1')
for p in ps:
a = p.find('a')
urls.append(str(a['href']))
s = random.randint(5,30)
print(str(i)+'page done,'+str(s)+'s later')
time.sleep(s)
return urls
构造数据请求
在获取了所有的职位数据的url之后,使⽤requests访问这些url发现,并不能顺利获取数据。因此,可以考虑在请求中加⼊headers数据,其中包含cookie和User_Agent:
User_Agent ='Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
cookie ='guid=14842945278988500031; slife=indexguide%3D1'
headers ={'User-Agent': User_Agent,'cookie': cookie}
这样,可以成功请求每个职位的详情页⾯数据:
数据解析
数据解析⾸先是明确数据需求,这⾥将数据尽可能多的抓取下来。
以职位要求⼀栏为例,通过访问多个页⾯对⽐发现,这⼀栏可能显⽰的要求个数不⼀样:
这⾥包括了经验、学历、招聘⼈数和发布时间
⽽这⾥则没有对于经验的要求。