Python3自学 爬虫实战拉钩-爬虫-Pythonpython

爬虫-拉勾招聘需求词频分析

2017-11-20  本文已影响406人  谦面客

本文实现拉勾网的爬虫,抓取招聘需求,统计出的词频前70的关键词,当然数量可以自己定,以深圳市的python招聘岗位为例。

1、爬虫老套路,分析浏览器请求,然后模仿之

先手动打开拉勾的招聘链接,进行搜索,观察浏览器的行为

https://www.lagou.com/zhaopin/
搜索python后页面显示很多职位信息,然后打开 chrome 开发者工具查看这个页面的response,发现响应中找不到岗位信息 查看开发者工具中的响应

这样看来就是用ajax来请求的数据了,把这个ajax请求找到,发现岗位信息都在这个响请求中,form data中的pn就是页码,kd是关键字


找到响应的ajax请求

于是模仿这个来发起请求,先获取第一页(这里有一个坑,如果请求头没有 Referer 字段,请求不到数据,反爬的常用手段,直接复制上面找到的请求中的就行)

import requests
import  json
 
 
class LagouCrawl(object):
 
    def __init__(self):
        self.url = "https://www.lagou.com/jobs/positionAjax.json"
        # 请求头
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",
            "Referer": "https://www.lagou.com/jobs/list_python"
        }
        # 查询字符串
        self.params = {
            "city": "深圳",
            "needAddtionalResult": False,
            "isSchoolJob": 0
        }
        # 表单数据
        self.data = {
            "first": True,
            "pn": 1,
            "kd": 'python'
        }
 
    def start_crawl(self):
        response = requests.post(self.url, params=self.params, data=self.data, headers=self.headers)
        data = response.content.decode('utf-8')
        dict_data = json.loads(data)
        print(dict_data)
 
if __name__ == '__main__':
    spider = LagouCrawl()
    spider.start_crawl()

这里得到一个 json 数据,里面有每条招聘的hr信息,招聘信息,我们需要的是以下的信息,都可以得到,以便于持续翻页得到所有的数据:

整个数据比较长,只展示 positionId 的位置


部分json数据字段

拼接出详情页的url

def build_detail_url(self, data, num):   # num 是一页的数量
    for i in range(num):
        position_id = data['content']['positionResult']['result'][i]['positionId']
        url = INFO_URL % position_id

然后再访问详情页,通过 xpath 提取详情页内的需求文字(需要掌握xpath提取规则),下面的 info_text 就是提取出的文字

from lxml import etree
 
def parse_html(self, html):
    obj_xpath = etree.HTML(html)
    node = obj_xpath.xpath("//dd[@class='job_bt']")
    info_node = node[0]
    info_text = info_node.xpath("string(.)").strip()
    return info_text

调用下面方法,得到的数据保存到 txt 中

def save_data(self, data):
    with open('info.txt', 'a', encoding='utf-8') as f:
        f.write(data)

这样得到的只是一页的,修改上面的代码把请求的页码做一个累加,爬取所有(连续爬取会出现问题,拉勾设置了访问频率,大概一分钟5次的样子,需要延时

2、得到数据,利用它来干一些事情

用 jieba 分词读取所有内容进行分词,并使用 wordcloud 生成词频图,setting.py 设置一些频率高会影响结果的词与默认的停用词并集,一起过滤。

import jieba.analyse           # 导入结巴分词
import numpy as np             # numpy
from wordcloud import WordCloud, STOPWORDS    # 词云工具和自带的的停用词
from PIL import Image              # 图片处理
from setting import STOPWORD_NEW    # 自定义了一个setting.py,过滤一些无关的词
 
 
def handle(filename, stopword):
    with open(filename, 'r', encoding='utf-8') as f:
        data = f.read()
 
    wordlist = jieba.analyse.extract_tags(data, topK=70)   # 分词,取前70
    wordStr = " ".join(wordlist)               
 
    hand = np.array(Image.open('hand.jpg'))    # 打开一张图片,词语以图片形状为背景分布
 
    my_cloudword = WordCloud(              # wordcloud参数配置
        background_color = 'black',   # 背景颜色
        mask = hand,                  # 背景图片
        max_words = 300,              # 最大显示的字数
        stopwords = stopword,         # 停用词
        max_font_size = 60,           # 字体最大值
    )
 
    my_cloudword.generate(wordStr)          # 生成图片
    my_cloudword.to_file('wordcloud.png')    # 保存
     
if __name__ == '__main__':
    handle('python.txt', STOPWORDS | STOPWORD_NEW)

3、最后把整个程序再修改一下

修改后目录结构如下:


目录结构

整个过程:爬虫启动时,开启两个协程,一个请求获取json数据,构建详情页url,扔进队列中,另一个从队列拿取url,爬岗位需求(这里可以用多个协程一起爬的,但拉勾访问频率限制了,只用了一个,中间休眠很久,很慢),用 queue.join() 阻塞主进程,当队列任务执行完后调用 HandleData 模块的方法,读取数据生成图,效果图如下。

背景图
词云效果
个人博客: 拉勾爬虫
附上代码,仅供参考: 拉勾招聘

END

上一篇下一篇

猜你喜欢

热点阅读