1. 程式人生 > >爬蟲2.1-scrapy框架-兩種爬蟲對比

爬蟲2.1-scrapy框架-兩種爬蟲對比

目錄

scrapy框架-兩種爬蟲對比和大概流程

注:spider.py指使用命令列建立的爬蟲主檔案

1. 傳統spider爬蟲

建立scrapy專案,首先進入想建立專案的目錄,然後cmd輸入:

scrapy startproject projectname # projectname 即是專案名
cd projectname
scrapy genspider spidername “xxxx.com” 

spidername就是爬蟲檔名 xxxx.com 用於限定爬蟲爬取的範圍爬蟲名,其與專案名不能相同

為了方便執行,之間在project目錄下建立start_project.py 來執行整個專案

~start_project.py
from scrapy import cmdline
cmdline.execute("scrapy crawl qsbk_spider".split())

簡單兩句話,要使用.split()是因為這裡引數值接收列表,分裂之後恰好是列表,然後才能被執行。

回到spider.py(爬蟲主要模組,用於解析),這裡已經幫我們自動生成了一些引數,在parse函式中,response引數使用xpath語法,得到的是SelectorList類的物件(該類是scrapy框架定義的),然後可以使用for語句遍歷其中,獲得Selector類,還是可以使用xpath語法獲取資料,這裡由一個很方便的函式.get() 直接獲取字串,再使用.strip()可以直接獲取沒有空格換行等的文字。

示例程式碼
    def parse(self, response):
        contentLeft = response.xpath("//div[@class='col1']/div")
        for content in contentLeft:
            author = content.xpath(".//h2/text()").get().strip()    # get 方法獲取Selector中的第一個文字 返回str型別    getall方法獲取Selector中的所有文字  返回一個列表
            joke = content.xpath(".//div[@class='content']/span/text()").get().strip()
            info = XXItem(author=author, joke=joke)
            yield info   # 推送到piplines.py中進行下一步的資料存入操作

2. crawl型爬蟲

在cmd中建立專案和爬蟲

scrapy startproject projectname
cd projectname
scrapy genspider -t crawl spidername "domain_name"

可見建立爬蟲時便與傳統spider不同,然後進入spider.py

# 專案名為wxapp,爬蟲名為wxapp_spider.py
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from wxapp.items import WxappItem  # 匯入items中定義好的資料類,方便json格式寫入
class WxappSpiderSpider(CrawlSpider):
    name = 'wxapp_spider'
    allowed_domains = ['wxapp-union.com']
    start_urls = ['http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1']  # 從第一頁開始
    rules = (
        # Rule 1用於從開始頁面向後面找到相同模式的url,所以follw選擇True,
        Rule(LinkExtractor
             (allow=r'.+mod=list&catid=2&page=\d+'), follow=True),
        # Rule 2用於在Rule 1模式的頁面下,找到真正需要解析資料的url,回撥函式一定要改名字。
        Rule(LinkExtractor(allow=r'.+/article-.+\.html'), callback='parse_info', follow=False),)

    def parse_info(self, response):
        title = response.xpath(r"//h1[@class='ph']/text()").get()  #獲取標題
        author = response.xpath(r"//p[@class='authors']/a/text()").get()  # 獲取作者
        contents = response.xpath(r"//td[@id='article_content']//text()").getall()  
        # 獲取內容   因為td下面還有很多標籤所以要用//text() 之後再.getall()
        content = ''.join(contents).strip()  
        # 巧妙用法 join將列表中的每一項依次放入  加上.strp() 去掉多餘的換行和空格
        info = WxappItem(title=title, author=author, content=content)  #建立info物件
        yield info  # 推送給pipelines.py

在多個規則下,一定要注意callback和follow引數,判斷需要在新的頁面中繼續跟進符合正則的url。

比如獲取職位簡介列表的url就需要跟進,而職位的詳情頁面找到相同的url時不需要跟進,按照職位列表往下遍歷即可。

所以,crawl型爬蟲適合於整站爬取,傳統spider型爬蟲適合小規模爬取

crawl型爬蟲引數講解

另外需要使用 LinkExtractors連結提取器:
class scrapy.linkextractors.LinkExtractor(
    allow = (),
    deny = (),
    allow_domains = (),
    deny_domains = (),
    deny_extensions = None,
    restrict_xpaths = (),
    tags = ('a','area'),
    attrs = ('href'),
    canonicalize = True,
    unique = True,
    process_value = None
)
主要引數講解:

allow:允許的url。所有滿足這個正則表示式的url都會被提取。
deny:禁止的url。所有滿足這個正則表示式的url都不會被提取。
allow_domains:允許的域名。只有在這個裡面指定的域名的url才會被提取。
deny_domains:禁止的域名。所有在這個裡面指定的域名的url都不會被提取。
restrict_xpaths:嚴格的xpath。和allow共同過濾連結。

Rule規則類:
定義爬蟲的規則類。以下對這個類做一個簡單的介紹:

class scrapy.spiders.Rule(
    link_extractor, 
    callback = None, 
    cb_kwargs = None, 
    follow = None, 
    process_links = None, 
    process_request = None
)
主要引數講解:

link_extractor:一個LinkExtractor物件,用於定義爬取規則。
callback:滿足這個規則的url,應該要執行哪個回撥函式。因為CrawlSpider使用了parse作為回撥函式,因此不要覆蓋parse作為回撥函式自己的回撥函式。
follow:指定根據該規則從response中提取的連結是否需要跟進。
process_links:從link_extractor中獲取到連結後會傳遞給這個函式,用來過濾不需要爬取的連結。

3. 迴圈頁面請求

找到迴圈條件和結束標準
在spider.py中
def parse(self, response):
    ...
    設定好迭代退出的條件
    使用yield scrapy.Request(url, callback=self.parse)  重複呼叫

示例:
def parse(self, response):
       ..... # 解析資料的函式
        next_url = response.xpath("//ul[@class='pagination']/li[last()]/a/@href").get()
        if re.match(r'/\w*/\w*/\d*/', next_url) is None:
            return
        else:
            yield scrapy.Request(self.base_domain+next_url, callback=self.parse)    
            # 這裡 self.base_domain+next_url 就是下一個頁面的url,之後回撥函式使用它自己,到了最後一頁處理完資料 達成if判斷條件退出。這裡用正則實際上由裝逼的意思,判斷一下長度就可以了

4. scrapy框架爬蟲的大致流程

使用命令列建立爬蟲專案

>> scrapy startproject [projectname]
>> cd [projectname]
>> scrapy genspider -t crawl [爬蟲名字] [域名]  or  scrapy genspider [爬蟲名字] [域名]  

使用IDE開啟專案,並在projectname下建立start.py用於啟動整個專案,注意scrapy框架只能這樣啟動。

~ start.py
from scrapy import cmdline
cmdline.execute('scrapy crawl [爬蟲名字]'.split())

修改[spidername].py

按需求修改解析函式,如果是crawl型爬蟲還需要修改和新增Rule

修改items.py

將需要的引數寫好

示例:
class xxItem(scrapy.Item):
    author = scrapy.Field()
    joke = scrapy.Field()

修改pipelines.py

pipelines.py主要用於按需求儲存資料。

看需求是否修改或新增中介軟體---middlewares.py

最後按照需求修改settings.py

settings.py
修改ROBOTSTXT_OBEY = False
開啟headers  DEFAULT_REQUEST_HEADERS 加入User-Agent  Cookie   
開啟並修改piplines設定  ITEM_PIPELINES
開啟延時 DOWNLOAD_DELAY
開啟中介軟體 DOWNLOADER_MIDDLEWARES

實戰程式碼可以看另一個筆記:scrapy框架-圖片分類下載