(1条消息) python成功爬取拉勾网

python成功爬取拉勾网(一个小白的心里路程)

最开始想爬取拉钩是因为半年前上python实验课的时候,老师给了两个任务,一个时爬取糗百的笑话内容,另一个时爬取拉勾网的职位信息,当时因为课时紧张的缘故,老师讲解了关于爬虫的相关的库(requests,BeautifulSoup库等)的基本使用方法,发下了爬取糗百网的源码,让我们自己试一试,说是拉勾网不好爬取,目前的水平不够。疫情在家这几天我基本可以容易的爬取静态网页相关的内容,便想的试试爬取拉钩。

先观察网页源码:

很容易从源码看出所有相关的信息都放在li标签的属当中,具体的工资值放在span标签当中

我用直接用原来爬取静态网页的方法直接爬取:

import bs4import requestsimport refrom bs4 import BeautifulSoupurl = 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='try:     hd = {'user-agent': 'chorme/10'}     r = requests.get(url, headers=hd)     r.raise_for_status()     r.encoding = r.apparent_encoding     text = r.text     #print(text)except:     print("")soup = BeautifulSoup(text,'html.parser')#print(soup.prettify())'''salary = re.findall(r'<span class="money">(.*?)</span>',str(text),re.S)print(salary)'''for i in soup.find_all('li',attrs={'class':'con_list_item first_row default_list'}):     print(i)

代码中很容易看出,我用正则表达式对span标签进行查找,可是有返回的结果,但并不是自己想要的结果,后用soup.findall方式尝试对li标签直接进行查找,但却返回的是空的结果,但之前输出返回的网页源码内容均存在,我想不通是为什么。。。

一开始我认为是正则表达式出错,但检查过后并不是这样的错误,我便上网查找大佬们已经成功的案例,发现大佬代码中的headers内容不仅仅只是伪装的了发起请求的浏览器,而且还带了许多我没有见到的方法属性值,我也更换了相同的头部进行了再次尝试。。。

try:     hd = {          'Accept': 'application/json, text/javascript, */*; q=0.01',          'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=',          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'     }     r = requests.get(url, headers=hd)     r.raise_for_status()     r.encoding = r.apparent_encoding     text = r.text     #print(text)except:     print("")

出现了这样的错误

到这里开始我便知道不能轻易的爬取拉钩,我便开始了解拉钩的反爬机制。

常见的反爬虫策略

请求头校验
这应该是最常见最容易解决的反爬虫。python的库自动生成的请求头的’user-agent’里常常带有python这样的关键字,网站一看就发现并不是正常的用户访问,直接拒绝请求。有些网站还会注意请求头里的’referer’这样的属性,所以在构建爬虫的时候,伪装请求头是必须的,尤其是’user-agent’这一项。
cookie校验
有些网站会检验访问的时候携带的cookie,如果是直接向某个指定url发起连接而没有携带上一级网页的cookie,就会拒绝你的访问。
IP校验和设备ID校验
检查访问的IP地址已经是反爬虫的常见手段。当某一个IP频繁访问就会激活网站的反爬虫机制,所以IP池的建立和维护也是爬虫工程师的必修功课。每一个设备都有一个唯一的device-id,部分网站会通过检查频繁访问的设备ID进行反爬虫,当遇到了这样的网站的时候,做设备ID的伪装也是必要的。
通过网页动态加载提高爬取门槛
静态网站一个简单的请求就能拿到所有信息,动态网页加载会让爬虫工程师花更多的精力在网页的分析上。当然,任何网站都是能爬的,只是简单和困难的区别而已。 通过登陆提高爬取门槛很多网站会把信息隐藏起来,只对登陆用户可见,同时大部分网站都会有验证码,以大名鼎鼎的12306的验证码最为著名。同时和登陆一起做反爬虫的还有登陆元素的动态生成,所以熟练的做模拟登录和cookie池的维护也是必须会使用的技能。

这是我查找的反爬资料,拉钩网本身属于动态页面,请求信息返回在json数据格式当中,而且在模拟请求访问的时候,头部信息中不带本页面的cookies信息也无法正确返回所要的内容,其反爬方式囊括可上述所有的基本反爬机制。

按我自己的理解来解析反爬(模仿大佬们的路程加自己的理解)

使用谷歌浏览器来搜索拉勾网,用f12来查看器其网页请求信息等。(只能是谷歌浏览器)

在Network -> XHR -> Headers 中记录了所有头部的信息,包括url链接,data内容,请求方式,cookies等所有相关的内容,可以用这些东西去拼接更加完整的请求头部。

这里附上一个关于谷歌network详解的链接,因为是一位csdn大佬缩写,很详细。
network详解

在Network -> XHR -> Preview中可以找到请求返回的信息,是josn格式

所以在爬取信息处理时我们可以采用json数据格式来处理数据。在查阅大佬们完成的代码中,可以得出,要想正确的获取请求信息,关键在于cookies,因为拉钩网的反爬机制在设置时头部信息中必须包含本页面所带的cookies信息,需要获取搜索结果那一页的cookie 以及header里面需要添加Accept、Referer、User-Agent。

在对cookise的信息处理时,requests库的session会话对象可以跨请求保持某些参数,说白了,就是比如你使用session成功的登录了某个网站,则在再次使用该session对象求求该网站的其他网页都会默认使用该session之前使用的cookie等参数

尤其是在保持登陆状态时运用的最多,在某些网站抓取,或者app抓取时,有的时强制登陆,有的是不登陆返回的数据就是假的或者说是不完整的数据,那我们不可能去做到每一次请求都要去登陆一下怎么办,就需要用到保持会话的功能了,我们可以只登陆一次,然后保持这种状态去做其他的或者更多的请求。

在了解了整个后,直接上整个源代码:

import requestsimport jsonimport timeurl_request = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'   #network -> headers中显示的请求链接url_html = 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='   #网页显示访问链接hd = {    'Accept': 'application/json, text/javascript, */*; q=0.01',    'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=',    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}'''爬取多页职位信息for i in range(1,6):    data = {        'first': 'true',        'pn': 'str(i)',        'kd': 'python'}'''#根据network -> headers显示的data来设置datadata = {        'first': 'true',        'pn': '1',        'kd': 'python'}# 创建一个session对象s = requests.Session()#发送请求,获得cookiess.get(url_html,headers = hd,data = data,timeout = 4)cookie = s.cookiesresponse = s.post(url_request,data = data,headers = hd,cookies = cookie,timeout = 4) #获得此次文本#print(response)response.encoding = response.apparent_encodingtime.sleep(6)#response.encoding = response.apparent_encoding#print(response.text)text = json.loads(response.text)#print(text)info = text["content"]["positionResult"]["result"]for i in info:    #print(i)    print(i["companyFullName"])    companyFullName = i["companyFullName"]    print(i["positionName"])    positionName = i["positionName"]    print(i["salary"])    salary = i["salary"]    print(i["companySize"])    companySize = i["companySize"]    print(i["skillLables"])    skillLables = i["skillLables"]    print(i["createTime"])    createTime = i["createTime"]    print(i["district"])    district = i["district"]    print(i["stationname"])    stationname = i["stationname"]    print("-------------------------")

运行后的结果:

我自己需要学习的还有很多,还年轻,努力!

(0)

相关推荐