通用爬蟲之站酷全站設計師資料爬取

咱們寫多幾個爬蟲就會發現,其實有不少相同的模塊,好比翻頁,好比網絡錯誤重試等。scrapy內部已經有很是完美的處理模塊,咱們只須要簡單配置便可使用,仍是接上一節咱們的爬蟲,這一次咱們將它封裝地更增強大。此次,咱們作一個通用爬蟲,實現隨機請求頭和換ip功能,除此以外將實現可配置化爬蟲,也就是說,咱們要爬取一個站點,只須要寫必要的連接篩選和解析規則便可,而無需像以前那樣寫不少冗餘的代碼塊。黑喂狗~html

工具環境

  • 語言:python3.6
  • 編輯器:Pycharm
  • 數據庫:MongoDB
  • 框架:scrapy1.5.1

舒適提示:

閱讀此文可能須要對scrapy框架有基本的瞭解,對xpath解析有一個基本的瞭解python

爬取思路

爬取站點:www.zcool.com.cn/數據庫

咱們須要的是每個設計師的資料頁面的信息,以下所示:json

邏輯其實很簡單:bash

  1. 找到儘量多的設計師網絡

  2. 找到他們的主頁(做爲跳板)併發

  3. 點開詳情頁資料,開始爬取信息框架

    若是你有看過上一節的爬蟲介紹,其實發現這一點也不難,不過是經過rule配置進行頁面追蹤,這裏咱們主須要找到儘量的的設計師,這裏我事先作過簡單的調研,這裏就不詳細我找設計的過程了,最後是在更多,設計師那裏找到的,加上首頁每一個做品的設計師,也有4000個,固然這裏可能有不少重複的,但和全量設計師,我當時有爬過一次,當時好像是有公開設計師的總量,不知道是25W仍是250W的註冊設計師,這樣算來的話,其實這4000設計師和25W根本不是一個量級的。那麼咱們就須要找別的入口,看哪裏還儘量能夠找到不少的設計師dom

    這裏有我已經發現的地方scrapy

  • 第一個是設計師頁面的不一樣類型的選項,還有按照城市區分的
  • 設計師首頁或做品也下面的訪客和留言
  • 每一個設計師的關注對象和粉絲

我最後選擇的是每一個設計的關注和粉絲,由於對於第一個,我可能須要將每一個城市的id記錄在案,而後再進行了詳細的拆分,生成根據城市和類型的自由組合,而後再將這些組合的url做爲初始連接進行爬蟲,至關於爬取以前要進行一步預處理,不太適合scrapy通用爬取的方法

訪客和留言,你們能夠經過調度頁面分析功能,發現它其實並無在html中實時展現,而是經過動態加載的方式調取信息,爬取的時候一樣有限制,可能涉及解析json,考慮到要作通用爬蟲,因此沒有選擇此種方式

最後每一個設計師的關注對象和粉絲的方法,就很是簡單直接,可能會丟失一些歷來不關注的用戶。只要是有關注別人基本能夠找到

show me the code

核心的功能模塊我是照着大才哥的教程學習的,傳送門丟給你們:

juejin.im/post/5b026d…

你們能夠看一下大才哥的教程一步步實現,在此基礎上,我增長了一個自動換請求頭的功能和換代理的功能

1. 隨機請求頭:

import random
from scrapy import signals
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
class RandomUserAgentMiddleware(UserAgentMiddleware):
"""This middleware allows spiders to override the useragent"""

def init(self, settings, useragent='Scrapy'):
    super(RandomUserAgentMiddleware, self).init()
    self.useragent = useragent
    useragentfile = settings.get('USERAGENTLIST')
    if not useragentfile:
        ua = settings.get('USERAGENT', useragent)
        self.useragentlist = ua
    else:
        with open(useragentfile, 'r') as f:
            self.useragentlist = i.strip() for i in f.readlines()

@classmethod
def fromcrawler(cls, crawler):
    o = cls(crawler.settings)
    crawler.signals.connect(o.spideropened, signal=signals.spideropened)
    return o

def spideropened(self, spider):
    self.useragent = getattr(spider, 'useragent', self.useragent)

def processrequest(self, request, spider):
    useragent = random.choice(self.useragentlist)
    if self.useragent:
        request.headers.setdefault(b'User-Agent', useragent)

複製代碼

核心思路就是在settings內獲得的user-agent的文件路徑之地,以後再每次請求的時候,隨機再其中抽取一個,若是沒有拿到的話,就默認選擇配置中的默認請求頭

2. 隨機代理ip

相似的,咱們在發起請求以前,先得到本身搭建好的ip代理服務,得到可用代理ip,咱們只須要繼承HttpProxyMiddleware模塊的功能,替換ip便可,HttpProxyMiddleware已經爲咱們貼心地實現了諸如須要使用帳號密碼,http和https的使用等

完成它們以後,咱們只須要根據要求,實現對應的items.py(須要提取的字段對象)、rules.py(對頁面追蹤邏輯的規則定義)、loaders.py(解析頁面的處理)便可,若是要使用動態的url,例如初始須要指定多頁面,那就須要配置一下urls.py

對應站酷網,核心的思路在上面的思路中已經結束,代碼註釋中有每一步的追蹤步驟,不在贅述

'zcool': (
    # 追蹤下一頁
    Rule(LinkExtractor(restrictxpaths='//a@class="laypagenext"]')),
    # 提取如 https://www.zcool.com.cn/u/15472001 樣式的頁面
    Rule(LinkExtractor(allow='.www.zcool.com.cn\/u\/\d+$')),
    # 追蹤 https://www.zcool.com.cn/designer 頁面設計師主頁的連接
    Rule(LinkExtractor(restrictxpaths='//a@z-st="usercontentcard1username"]')),
    # 追蹤 https://www.zcool.com.cn/designer 篩選 | 推薦設計師 欄目的分頁
    Rule(LinkExtractor(restrictxpaths='//astarts-with(@z-st, "desingerfilterrecommend")]')),
    # 追蹤 https://www.zcool.com.cn/designer 篩選 | 不限職業 欄目的分頁
    Rule(LinkExtractor(restrictxpaths='//astarts-with(@z-st, "desingerfilterprofession")]')),
    # 原本準備使用訪客和留言來追蹤的,後來發現頁面是動態加載的,提取收到該信息,遂棄用
    # Rule(LinkExtractor(restrictxpaths='//a@class="usernick"')),
    # Rule(LinkExtractor(restrictxpaths='//a@class="visitor-name"')),
    # 追蹤 粉絲頁面
    Rule(LinkExtractor(allow='.?fans.')),
    # 追蹤 關注頁面
    Rule(LinkExtractor(allow='.?follow.')),
    # 追蹤 設計師資料頁,並回調給parseitem函數處理
    Rule(LinkExtractor(allow='.?profile.'), callback='parseitem'),
)

複製代碼

至此,一個通用的母體爬蟲便製做完畢,以後若是用來爬反爬蟲不是特別強的網站,一個爬蟲也不過就是分析網站和作頁面解析費點時間,作好這個以後,一個簡單的頁面爬蟲,我初略估計不會超過半小時便可

如今個人爬蟲還在提取中,目前單機採集速度大概在日採集5-6萬的樣子,若是要提速能夠本身在配置中增長併發

tail_qrcode.jpg
相關文章
相關標籤/搜索