需求:爬取腾讯招聘岗位 、翻页
https://careers.tencent.com/search.html?index=1
如下:
第一步 分析页面
1、数据在哪里获取?
我们在网页源代码中找下,是否有目标数据:
显然原代码中并没有关于招聘岗位的信息,所以我们不能对该url(https://careers.tencent.com/search.html?index=1)发起并获得响应,再替换page的数字来翻页,进而完成任务。
我们右键检查,在network-XHR中,可以发现下图右下角红框,点击看到response,ctrl+f搜索招聘岗位中的25927,发现了response中包含该数据。
,就确认了我们要的目标url就在对应的Headers中,见下图。
即目标url:
https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1625539350923&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex=1&pageSize=10&language=zh-cn&area=cn
我们打开上述目标url,搜索25927,有结果,就确认该目标url。
2、我们去发现目标url的规律,以实现翻页功能。
点击第2页,如下图:
得到第2页:
用第1页同样的方法,得到目标url:
https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1625541009650&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex=2&pageSize=10&language=zh-cn&area=cn
观察规律可知:只是pageIndex=1变成了pageIndex=2,所以我们替换这个数字就可以实现翻页功能。
第二步 代码实现
1 、创建scrapy项目
scrapy startproject tencent
2 、创建爬虫程序
scrapy genspider hr tencent.com
3 、实现逻辑
(1)爬虫文件代码:
import scrapy
import json
from tencent.items import TencentItem
class HrSpider(scrapy.Spider):
name = 'hr'
allowed_domains = ['tencent.com']
one_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1622635924738&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex={}&pageSize=10&language=zh-cn&area=cn'
start_urls = [one_url.format(1)] # 修改
def parse(self, response):
# 解析数据
data = json.loads(response.text)
for job in data['Data']['Posts']:
item = TencentItem()
item['job_name'] = job['RecruitPostName']
print(item)
# 翻页
for page in range(2,3):
url = self.one_url.format(page)
yield scrapy.Request(url=url)
(2)items文件代码
结果:
二、scrapy.Request(url, meta, callback)中meta参数的作用
Request的参数meta作用是将meta中的信息传递给下一个回调函数,使用过程可以理解为:
如果回调函数A,需要用到上一个函数B的数据,那我们可以在函数B中把该数据赋值给变量meta,让它传给回调函数A;且meta只接受字典类型的数据,所以,我们要把待传递的信息改成字典形式,即:
meta = {‘key1’: ‘value1’, ‘key2’: ‘value2’}
如果想在函数A中获取meta:
meta = response.meta
如果想在函数A中取出value1:
value = response.meta[‘key1’]
案例:
在spider爬虫中:
三、补充需求:爬取岗位职责,如下图
1、页面分析
用上述方法同样可以得到下图,
可以确定目标url在对应的Headers中:
https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1625549914055&postId=1411251485387268096&language=zh-cn
再看另一个岗位的工作职责,得到目标url:
https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1625550274965&postId=1260769753539026944&language=zh-cn
(timestamp是时间戳,不影响访问)
可以发现,只是postId不同,我们替换不同的postId值,就可以得到不同岗位职责。
那么我们去哪里找postId值来替换呢?
比如第一个目标url的postId=1411251485387268096,我们去哪里找到呢?!
如下图:在前述爬取岗位时,得到的url
打开该url,搜索1411251485387268096,得到!
所以,postId就在我们爬取岗位名称时就可以一起爬取下来,再拼接成岗位职责的目标url。
2、代码实现
import scrapy
import json
from tencent.items import TencentItem
class HrSpider(scrapy.Spider):
name = 'hr'
allowed_domains = ['tencent.com']
one_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1622635924738&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex={}&pageSize=10&language=zh-cn&area=cn'
two_url = 'https://careers.tencent.com/tencentcareer/api/post/ByPostId?timestamp=1622637678428&postId={}&language=zh-cn'
start_urls = [one_url.format(1)] # 修改
def parse(self, response):
# 解析数据
data = json.loads(response.text)
for job in data['Data']['Posts']:
item = TencentItem()
item['job_name'] = job['RecruitPostName']
post_id = job['PostId']
# 获取详情页的url
detail_url = self.two_url.format(post_id)
yield scrapy.Request(
url=detail_url,
callback=self.detail_content,
meta={'item':item}
)
#print(item)
# 翻页
for page in range(2,3):
url = self.one_url.format(page)
yield scrapy.Request(url=url)
def detail_content(self,response):
item = response.meta['item']
data = json.loads(response.text)
item['job_duty'] = data['Data']['Responsibility']
print(item)
结果: