事情是这样的:
这天和女朋友闲聊天,女朋友说她很累,不想做了?
此时我心中一万个想法涌上心头,且 “绿” 字在我头上围绕许久
正想问,她来了一句,想换工作,emmm…我想多了
此时男朋友的作用来了,马上就安慰她,你先干着吧,边干着边找新机会
然后我立马去爬取了岗位给女朋友选择,还给她小小的总结了一下工作需求
正文:
我们这次就是干拉钩!!
搜索框输入岗位,点进去然后就开始分析页面:
由此我们得出:
- 这个页面是动态加载的
这个网页就比较难弄了,兄弟们,我们只能慢慢搞了
首先,我们来F12抓包
找到这个ajax请求的包,然后里面是就是我们需要的数据
然后我们就是构建headers发送请求呗,注意:这个是post 请求
那么涉及到post请求的,就一定会涉及到data表单提交
然后就是cookie,它这个构建headers时里面必须携带,且需要实时更换,如果不携带或者不跟新,爬取不了几次就废了,再爬取就是,访问太频繁
基于目前拉勾的反爬总结(以后的猜不到哈哈哈~),现在要突破的点
敲黑板划当向重重重点总结!!!!!
- ajax请求,需要抓包分析
- 请求需要携带cookie,并且每次ajax请求cookie都要实时更换主页请求里面的cookie
- headers里面至少有 referer、user-agent、cookie
- referer 必须是ajax请求的里面的
- cookie 必须是主页请求里面的
我们怎么获取请求页的cookie,并且实时传到ajax请求页里呢
requests里面有个函数是Session(),获取到session,用session去请求主页地址,然后请求完成后,session.cookie会拿到主页的cookie,最后把cookie传到post请求里面就可以去拿到数据
session = requests.Session()
session.get(url=url, headers=headers)
cookies = session.cookies
response = session.post(url=api_url, data=data, headers=headers, cookies=cookies)
我们点击第二页第三页还会显示这个
first:这个是判断是不是第一页
pn:页页码数
kd:关键字
sid:这个是一个参数,也得处理一下
这个参数我在ajax请求里找到了就是一个名字为showId的,参数一样的,到时候直接取出来
所以在这里做了一个判断:
if page == 1:
data = {
'first': 'true',
'pn': page,
'kd': '会计',
}
else:
data = {
'first': 'false',
'pn': page,
'kd': '会计',
'sig': sid
}
总结一下:
不得不说,拉勾的反爬做的是真的太狠了,而且实时更新的特别快,如果不细研究,很多爬虫小白,应该会果断放弃,就比如,在cookie那里,如果不及时更新cookie,应该到第四五次,一直到后面就是返回的都是请求太频繁了,还有就是不知道怎么更新cookie
所以我们在学习的过程中,多思考,多看别人的代码,还得要多试着敲代码,千万不要盲目跟风,这样你学不学没有区别,没有自己的思想,就等同于代码也是死的
下面是全部代码
import csv
import requests
import time
import random
class LagouSpider:
def __init__(self):
# 请求页url
self.url = 'https://www.lagou.com/jobs/list_%E4%BC%9A%E8%AE%A1?labelWords=&fromSearch=true&suginput='
# 抓包ajax请求url
self.api_url = 'https://www.lagou.com/jobs/positionAjax.json?city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false'
self.sid = ""
self.f = open('lagou_kuaiji.csv', 'w', encoding='utf8', newline='')
self.writer = csv.writer(self.f)
def get_html(self, page):
headers = {
'Referer': 'https://www.lagou.com/jobs/list_%E4%BC%9A%E8%AE%A1?labelWords=&fromSearch=true&suginput=',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
'Cookie': 'RECOMMEND_TIP=true; user_trace_token=20201209073852-3f99a44d-709b-470d-9792-c179ae054a73; LGUID=20201209073852-f5eeca23-562a-42f3-a2d7-65c79deea2a7; _ga=GA1.2.879607015.1607470733; privacyPolicyPopup=false; LG_HAS_LOGIN=1; showExpriedIndex=1; showExpriedCompanyHome=1; showExpriedMyPublish=1; hasDeliver=620; index_location_city=%E5%8C%97%E4%BA%AC; _gid=GA1.2.373472203.1622639521; JSESSIONID=ABAAAECABIEACCA7735A9FDB929D2E2067B741FBDE49AA5; WEBTJ-ID=20210603213409-179d214cd40204-0ca37dc64f5989-317f0a5e-1296000-179d214cd412e9; sensorsdata2015session=%7B%7D; gate_login_token=d6eb9ac74e0358445cbfa2eb8b733be5c3c551515c42c4b2025efe185eacfca4; LG_LOGIN_USER_ID=0cca1fc2888bb379c4413fd9d0d4e0904b027bdc35dd0004d51d750a3472fd80; _putrc=909B320E8ACE6FCC123F89F2B170EADC; login=true; unick=%E6%9D%A8%E6%97%AD%E5%8D%8E; __SAFETY_CLOSE_TIME__19273945=1; PRE_UTM=; __lg_stoken__=edcc0c5a8214e0f3bc7226ec6a5331432276d3465c278811b5755819feca760eedfd545ebe69802e41f863bfff9030ef9b63695b69c913445aa580d27797d0e64c7df6bd12e3; _gat=1; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1622733080,1622733267,1622733466,1622821703; LGSID=20210604234823-118a6881-40ea-459f-81bb-b5736198da76; PRE_HOST=www.baidu.com; PRE_SITE=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DvH-p2riimbmz7mRXHRp1dfI4fL7qh76cP3fiVW6xcsa%26wd%3D%26eqid%3Dad23d8cb0000aa540000000360b8da4a; PRE_LAND=https%3A%2F%2Fwww.lagou.com%2F; TG-TRACK-CODE=index_search; SEARCH_ID=71535e6f530d43e9a2589a5cc2c13843; X_HTTP_TOKEN=ea215d6478a8c212717128226104e601afd8a585ad; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2219273945%22%2C%22first_id%22%3A%2217644b8d4de147-026085178434b3-317f0a5e-1296000-17644b8d4e0194%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%22%2C%22%24os%22%3A%22UNIX%22%2C%22%24browser%22%3A%22Chrome%22%2C%22%24browser_version%22%3A%2280.0.3987.116%22%2C%22lagou_company_id%22%3A%22%22%7D%2C%22%24device_id%22%3A%2217644b8d4de147-026085178434b3-317f0a5e-1296000-17644b8d4e0194%22%7D; LGRID=20210604234838-03d85571-8169-4070-a28d-914587246fad; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1622821719',
}
if page == 1:
data = {
'first': 'true',
'pn': page,
'kd': '会计',
}
else:
data = {
'first': 'false',
'pn': page,
'kd': '会计',
'sid': self.sid
}
# 取出并传递cookie
session = requests.Session()
session.get(url=self.url, headers=headers)
cookies = session.cookies
response = session.post(url=self.api_url, data=data, headers=headers, cookies=cookies)
data = response.json()
return data
def parse_html(self, data):
# 取出数据
result = data['content']['positionResult']['result']
# 取出sid值
self.sid = data['content']['showId']
for li in result:
item = {
# 取出需要的信息
'positionName': li['positionName'],
'district': li['district'],
'salary': li['salary'],
'workYear': li['workYear'],
'education': li['education'],
'companyFullName': li['companyFullName'],
'industryField': li['industryField'],
'financeStage': li['financeStage'],
'companySize': li['companySize'],
'companyLabelList': li['companyLabelList'],
'skillLables': li['skillLables'],
'positionAdvantage': li['positionAdvantage'],
}
print(item)
self.writer.writerow(item.values())
def run(self):
for page in range(1, 31):
self.parse_html(self.get_html(page))
time.sleep(random.uniform(3, 4))
self.f.close()
if __name__ == '__main__':
spider = LagouSpider()
spider.run()