爬取招聘数据 | scrapy 前程无忧51job

目录

  • 1. 预备知识
  • 2. 抓取目标结构
  • 3.抓包分析
    • 3.1 抓包分析url地址
    • 3.2 分析页码规律
    • 3.3分析数据存储位置
  • 4. 正则表达式的应用
  • 5. 代码编写
    • 5.1 start_requests
    • 5.2 正则提取数据
    • 5.3 提取职位的详情信息

1. 预备知识

python语言,scrapy爬虫基础,正则表达式

2. 抓取目标结构

  1. 职位列表中的以下信息:
    爬取招聘数据 | scrapy 前程无忧51job_第1张图片
  2. 点击职位,进入职位详情页中,提取以下信息:
    爬取招聘数据 | scrapy 前程无忧51job_第2张图片

3.抓包分析

3.1 抓包分析url地址

先进入到我们的页面中来,选择想要爬取的城市,url地址会发生相应的变化并刷新,如下图所示:
爬取招聘数据 | scrapy 前程无忧51job_第3张图片
复制地址栏的url链接地址如下:https://search.51job.com/list/120200,000000,0000,00,9,99,+,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=
根据第三章学到的知识,我们尝试对该url链接进行删减并测试删减后的url是否对访问结果产生影响,测试后删减的url结果如下:

https://search.51job.com/list/120200,000000,0000,00,9,99,+,2,1.html

访问并对比原网页可以发现,删减参数后的url地址所请求的页面,与原url请求的网页相差不大,均存在我们想要提取的信息。
结果如下:
爬取招聘数据 | scrapy 前程无忧51job_第4张图片

3.2 分析页码规律

我们先打开删减版的url对应的页面,为了分析页码请求数据的规律,我们先将滑块移到最后,点击抓包工具中的clear按钮,清空当前存在的请求列表,防止之前存在的请求列表对我们的分析进行干扰,最后,点击第二页,查看抓包工具抓取到的url链接,同时注意url地址栏的变化情况,操作如下所示:
爬取招聘数据 | scrapy 前程无忧51job_第5张图片
爬取招聘数据 | scrapy 前程无忧51job_第6张图片
分析上图,我们可以看到数据依然是通过ajax异步传递的,同时url链接再次变成了众多参数的url,但是这里我们可以发现url地址的变化有非常关键的一点:
原来的url链接:https://search.51job.com/list/120200,000000,0000,00,9,99,+,2,1.html
变成了以下链接:
https://search.51job.com/list/120200,000000,0000,00,9,99,+,2,2.html

3.3分析数据存储位置

我们尝试将抓到的ajax的请求进行访问时,得到了以下结果:
爬取招聘数据 | scrapy 前程无忧51job_第7张图片
单独进行这条链接的请求,返回的只能是整个前端的页面数据,并不像我们想象中的是一些json格式的字符串,所以我们没有办法利用上一章实验的思路进行数据提取,只能通过分析url的响应,查找数据存在的位置。
接下来我们尝试查找数据存在的位置,首先,复制前端咱们想要抓取的数据,在全局中搜索这段数据出现的位置以及所对应的url链接,然后抓包工具的network模块找到这条url,按ctrl+f进行搜索,流程如下图所示:
爬取招聘数据 | scrapy 前程无忧51job_第8张图片
爬取招聘数据 | scrapy 前程无忧51job_第9张图片
爬取招聘数据 | scrapy 前程无忧51job_第10张图片
可以看到数据 是存放在url对应的响应中的script标签下,我们可以尝试用正则表达式进行匹配。

4. 正则表达式的应用

首先,找到想要提取的数据前后的字符存在规律,例如:在本章中,“window.SEARCH_RESULT = ”是json数据前面的字符串,“”是json数据后面的字符串,如下图所示:
爬取招聘数据 | scrapy 前程无忧51job_第11张图片
接下来我们要利用正则表达式匹配到两个字符串中间的json数据。新建一个test.py进行测试,提前写好正则表达式,有利于我们提高我们编写scrapy的效率。首先我们将这一行前端代码复制粘贴到我们的代码中,用变量html_str进行存储,如下图所示:

import re
# xxxx是前端中的json数据,数据过长,不易展示
html_str = ' window.__SEARCH_RESULT__ = {"xxxx"} '
# 这里是正则表达式的使用,将想要提取的字符串用(.*?)代替
# 前后分别加上原来相对应的字符即可
json_str = re.findall('window.__SEARCH_RESULT__ = (.*?)', html_str)[0]
# 使用JSON模块 将字符串转化JSON格式的数据
json_dict = json.loads(json_str)
# 查看其中的数据
for i in json_dict['engine_search_result']:
   print(i)

爬取招聘数据 | scrapy 前程无忧51job_第12张图片

5. 代码编写

5.1 start_requests

def start_requests(self):
        base_url = "https://search.51job.com/list/200200,000000,0000,00,9,99,%25E5%25A4%25A7%25E6%2595%25B0%25E6%258D%25AE,2,{}.html"
        for i in range(1,21):
            next_page_url = base_url.format(i)
            # print(next_page_url)
            # 发送GET请求
            yield scrapy.Request(
                url=next_page_url,
                callback=self.parse
            )

5.2 正则提取数据

使用正则表达式提取想要的字符串,并使用json将字符串转换为json字典格式的数据,然后使用循环进入json数据列表中提取其中的数据,找到职位详情页的url地址后,再次进行请求该url,获取更多的职位信息。

def parse(self, response):
# 检查随机请求头是否设置成功 
        print(response.requests.headers)
        html_str = response.text
        # . 代表任意一个字符  
# ?代表匹配前面的子表达式0到1次    
# * 代表匹配前面的子表达式人任意次
        json_str = re.findall('window.__SEARCH_RESULT__ = (.*?)', html_str)[0]
        json_dict = json.loads(json_str)
        for data in json_dict['engine_search_result']:
				item = {}
            item['job_name'] = data['job_name']
            item['company_name'] = data['company_name']
            item['job_address'] = data['workarea_text']
            item['salary'] = data['providesalary_text']
            item['job_time'] = data['updatedate']
            # job_need是一个列表
            job_need = data['attribute_text']
            # join函数将上面的列表转换为字符串
            item['job_need'] = ",".join(job_need)
# 提取职位详情页对应的url
            job_detail_url = data['job_href']
            item['job_detail_url'] = job_detail_url
				# 请求职位详情页的url
            yield scrapy.Request(
                url=job_detail_url,
                meta={"item":item},
					 # 传递给新定义的提取详情页信息的url
                callback=self.parse_detail,
            )

5.3 提取职位的详情信息

这里详情页信息是非常常规的网页,直接用xpath就可以提取,没有任何反爬机制,同学们可以自行查看详情页信息进行提取

def parse_detail(self,response):
# 将上一步提取的数据,通过meta传递给item
        item = response.meta['item']
		  # 职位详情信息
        item["company_detail"] = response.xpath("//div[@class='bmsg job_msg inbox']//p/text()").extract()
		  yield item

爬取招聘数据 | scrapy 前程无忧51job_第13张图片
保存文件结果如下:
爬取招聘数据 | scrapy 前程无忧51job_第14张图片

数据获取直达:十万条数据集 2022/4/30更新
https://download.csdn.net/download/lijiamingccc/85245765

你可能感兴趣的:(爬虫,python)