python學習之路-爬取boss直聘的崗位信息


背景

想了解從事python相關崗位需要具備什么技能,於是就想從招聘網站上的職位需求入手,把信息獲取下來后,生成詞雲,這樣就能很直觀的看出來哪些技能是python相關崗位需要具備的了。

技術概覽

  1. scrapy
  2. request
  3. wordcloud
  4. jieba
  5. python37
  6. XPATH
  7. 正則表達式

具體內容

  1. 獲取到上海+python的崗位頁面
  2. 獲取每頁30個的崗位的職位信息
  3. 自動翻頁獲取
  4. 解決反爬的問題
  5. 生成詞雲

關於scrapy的介紹可以參考左邊鏈接,我就直接開始介紹我是怎么實現的吧。

打開boss直聘的web頁面,定位就是上海,輸入python之后,發現url發生了變化(query的值是python,city的值是101020100)這里我們可以驗證下,把query改成java后面就跳轉到java相關崗位的頁面,而city也是一樣的,101020100是上海市的編號,其他城市的編號可以直接在web源碼上獲取。



現在我們來看如何獲取崗位信息,手動操作的話就是點擊崗位標題即可進入詳細崗位介紹的界面,打開開發者工具可以發現崗位標題這里實際上是個跳轉鏈接,我們可以通過xpath(//[@class="name"]//@href)來獲取當前頁面的鏈接再配合正則'/job_detail.?.html'精確我們需要的鏈接,最后跟('https://www.zhipin.com')組合起來就是完整的url。

    def parse(self, response):
        job = response.xpath('//*[@class="name"]//@href').extract()
        job = re.findall('/job_detail.*?.html', str(job))
        print('job:{}'.format(job))
        for i in range(30):
            print('當前在{}項崗位'.format(i))
            job_url = 'https://www.zhipin.com'+job[i]
            yield scrapy.Request(url=job_url, callback=self.parse_job)

    def parse_job(self, response):
        item = BossItem()
        item['job_desc'] = response.xpath('//*[@class="job-sec"]//div[@class="text"]/text()').extract()
        yield item

翻頁,手動點擊翻頁可以看到page信息發生了變化,page的值就是實際的頁數,可以嘗試修改page驗證下,尤其是第一頁有可能不適用這個方法,scrapy自帶的start_urls列表就可以實現手動的翻頁。


start_urls = ['https://www.zhipin.com/c101020100/?query=python&page=1',
'https://www.zhipin.com/c101020100/?query=python&page=2',
'https://www.zhipin.com/c101020100/?query=python&page=3',
'https://www.zhipin.com/c101020100/?query=python&page=4',
'https://www.zhipin.com/c101020100/?query=python&page=5',
'https://www.zhipin.com/c101020100/?query=python&page=6',
'https://www.zhipin.com/c101020100/?query=python&page=7',
'https://www.zhipin.com/c101020100/?query=python&page=8',
'https://www.zhipin.com/c101020100/?query=python&page=9',
'https://www.zhipin.com/c101020100/?query=python&page=10']

反爬,我是設置了隨機的useragent以及ip代理。useragent可以幫助我們的爬蟲偽裝成普通的瀏覽器,而代理ip解決被服務器識別並且封ip的問題。這里不得不提一個坑,就是python37+scrapy1.7.1的環境跟舊的環境中間件的設置有變化的地方,就是request.meta['proxy']一定要改成request.meta['http_proxy'],才能用,不然就會一直各種報錯(10060,10061還有就是403,302等http的狀態碼)。我們也可以在setting文件中設置CONCURRENT_REQUESTS(Scrapy downloader 並發請求的最大值)為1,DOWNLOAD_DELAY(下載器在下載同一個網站下一個頁面前需要等待的時間)為30s,這樣也可以防止我們被封ip。免費的ip代理池的話可以通過右邊鏈接的教程獲取,親測可用。免費ip代理獲取教程

class MyUserAgentMiddleware(UserAgentMiddleware):

    def __init__(self, agents):
        self.agents = agents

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            agents=crawler.settings.get('USER_AGENTS')
        )

    def process_request(self, request, spider):
        agent = random.choice(self.agents)
        request.headers['User-Agent'] = agent
        print('now user-agent is:' + agent)

    def process_response(self,request,response,spider):
        return response

class ProxyMiddleware(HttpProxyMiddleware):
    '''
    設置Proxy
    '''

    def __init__(self, ip):
        self.ip = ip

    @classmethod
    def from_crawler(cls, crawler):
        return cls(ip=crawler.settings.get('PROXIES'))

    def process_request(self, request, spider):
        ip = random.choice(self.ip)
        request.meta['http_proxy'] = ip
        print('now ip is:'+ip)

    def process_response(self,request,response,spider):
        if response.status != 200:
            ip = random.choice(self.ip)
            request.meta['http_proxy'] = ip
            print('change ip is:' + ip)
            return request
        return response

最后的詞雲生成一開始我是寫在pipeline.py文件里,這樣scrapy會自動在獲取到數據后進行生成詞雲,但是我發現每獲取一次生成一次也很浪費時間,還是全部獲取完另外生成比較方便,這里就用到jieba分詞,分完后可以通過wordcloud設置詞雲的大小,詞匯量,背景,顏色,字體等等,有不合適的詞匯設置停用詞去掉即可。

class BossItem(scrapy.Item):
    #寫在item.py文件里
    # define the fields for your item here like:
      job_desc = scrapy.Field()
class BossPipeline(object):
#寫在pipeline.py文件里
    def process_item(self, item, spider):
        text = ''.join(item['job_desc'])
        d = path.dirname(__file__)
        with open(path.join(d, 'zhipin.txt'), 'a', encoding='utf-8') as f:
            f.write(text)
        return item
# encoding:utf-8
from os import path
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import jieba
#詞雲制作
d = path.dirname(__file__)
text = open(path.join(d, 'zhipin.txt'),encoding='utf-8').read()
stopwords = [line.strip() for line in open(path.join(d, 'ban.txt'), 'r').readlines()]
wordlist = jieba.cut(text)
outstr = ''
for word in wordlist:
    if word not in stopwords:
        if word != '\t':
            outstr += word
            outstr += " "
wordcloud = WordCloud(width=1000, height=1000, font_path='HYQiHeiY4-95W.otf').generate(outstr)
wordcloud.to_file(path.join(d,"cloud_word.png"))

總結

以上就是我使用scrapy框架的Spider來爬取BOSS直聘上職位信息的具體實現方式,其實一開始我想要爬不同地區的python相關的崗位,但是這樣一來就不能簡單的通過start_urls列表來實現翻頁,因為不同地區的頁數不固定,得先獲取到總頁碼,這里就涉及到:不同地區的url隊列、同一個地區的不同頁面的url隊列、同地區同頁面的不同崗位的url隊列,因此簡單的Spider無法實現,需要用到CrawlSpider,這里我就先寫了簡單版的,有機會再學習下CrawlSpider。這里生成的詞雲好像也沒有什么特別的參考價值,大家還是找一找自己心儀的崗位有針對性的去學習吧哈哈哈。源碼的話可以去我的github獲取。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM