CrawlSpider的功能
只要滿足某個條件的url,都給我進行爬取。那麼這時候我們就可以通過CrawlSpider來幫我們完成了。CrawlSpider繼承自Spider,只不過是在之前的基礎之上增加了新的功能,可以定義爬取的url的規則,以後scrapy碰到滿足條件的url都進行爬取,而不用手動的yield Request。
創建CrawlSpider爬蟲
如果想要創建CrawlSpider爬蟲,那麼應該通過以下命令創建:
scrapy genspider -t crawl [爬蟲名字] [域名]
LinkExtractors&Rule
需要使用LinkExtractor
和Rule
。這兩個東西決定爬蟲的具體走向。
1.LinkExtractors鏈接提取器:
使用LinkExtractors可以不用程序員自己提取想要的url,然後發送請求。這些工作都可以交給LinkExtractors,他會在所有爬的頁面中找到滿足規則的url,實現自動的爬取。以下對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共同過濾鏈接。
2.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中獲取到鏈接後會傳遞給這個函數,用來過濾不需要爬取的鏈接。
allow設置規則的方法:要能夠限制在我們想要的url上面。不要跟其他的url產生相同的正則表達式即可。
什麼情況下使用follow:如果在爬取頁面的時候,需要將滿足當前條件的url再進行跟進,那麼就設置爲True。否則設置爲Fasle。
什麼情況下該指定callback:如果這個url對應的頁面,只是爲了獲取更多的url,並不需要裏面的數據,那麼可以不指定callback。如果想要獲取url對應頁面中的數據,那麼就需要指定一個callback。
CrawlSpider爬取微信社區文章
1.創建爬蟲項目
scrapy startproject wxapp
2.創建wxappspider CrawlSpider爬蟲
scrapy genspider -t crawl wxappspider "wxapp-union.com"
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from wxapp.items import WxappItem
class WxappspiderSpider(CrawlSpider):
name = 'wxappspider'
allowed_domains = ['wxapp-union.com']
start_urls = ['http://www.wxapp-union.com/portal.php?mod=list&catid=1&page=1']
rules = (
Rule(LinkExtractor(allow=r'.+mod=list&catid=1&page=\d'), follow=True),
Rule(LinkExtractor(allow=r'.+article-.*'),callback='parse_detail',follow=False),
)
def parse_detail(self, response):
title = response.xpath("//h1[@class='ph']/text()").get()
authors = response.xpath("//p[@class='authors']/a/text()").get()
time = response.xpath("//span[@class='time']/text()").get()
content = response.xpath("//td[@id='article_content']//text()").getall()
content = ''.join(content).strip()
item=WxappItem(title=title,authors=authors,time=time,content=content)
yield item
import scrapy
class WxappItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
authors = scrapy.Field()
time = scrapy.Field()
content = scrapy.Field()
import json
class WxappPipeline(object):
def __init__(self):
self.fp = open("wxapp.js",'w',encoding="utf-8")
def process_item(self, item, spider):
item_json = json.dumps(dict(item), ensure_ascii=False)
self.fp.write(item_json)
return item
def close_spider(self,spider):
self.fp.close()
print("爬蟲結束")
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 1
# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 Safari/537.36',
}
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'wxapp.pipelines.WxappPipeline': 300,
}
from scrapy import cmdline
cmdline.execute("scrapy crawl wxappspider".split())
注:參考了網易雲知了課堂.