python scrapy拆解查看Spider類爬取優(yōu)設網(wǎng)極細講解
拆解 scrapy.Spider
本次采集的目標站點為:優(yōu)設網(wǎng)
每次創(chuàng)建一個 spider 文件之后,都會默認生成如下代碼:
import scrapy
class UiSpider(scrapy.Spider):
name = 'ui'
allowed_domains = ['www.uisdc.com']
start_urls = ['http://www.uisdc.com/']
def parse(self, response):
self.log()
繼承的基類 scrapy.Spider 自然就成了我們要研究的第一個內容,進入其源碼,發(fā)現(xiàn)如下內容。
scrapy.Spider 核心實現(xiàn)的是 start_requests 方法
Spider 主要進行的操作就是初始化 Request 請求,而這些都是通過 start_requests 實現(xiàn)的,詳細代碼為:
for url in self.start_urls:
yield Request(url, dont_filter=True)
對 start_requests 方法,你可以自己編寫同名函數(shù)覆蓋修改,編寫時發(fā)現(xiàn)了 make_requests_from_url 方法,該方法在最新版本的 scrapy 中已經(jīng)被廢除。
重寫 start_requests 方法 ,需要注意重寫時,必須返回一個可迭代對象,并且該對象包含 spider 用于爬取的第 1 個 Request,由于 scrapy 只調用一次該方法,所以你可以將登錄站點請求放置到該方法中。
import scrapy
from scrapy.http import Request
class UiSpider(scrapy.Spider):
name = 'ui'
allowed_domains = ['www.uisdc.com']
start_urls = ['http://www.uisdc.com/']
def start_requests(self):
print("重寫 start_requests")
yield Request(self.start_urls[0])
def parse(self, response):
print(response)
將登錄信息放置到 start_requests 中,代碼如下:
import scrapy
from scrapy.http import FormRequest
class UiSpider(scrapy.Spider):
name = 'ui'
allowed_domains = ['www.uisdc.com']
start_urls = ['http://www.uisdc.com/']
def start_requests(self):
print("手動 start_requests")
yield FormRequest("https://httpbin.org/post", formdata={"user": "ca"}, callback=self.parse)
def parse(self, response):
print(response.text)
scrapy.Spider 屬性值
name 屬性:
表示爬蟲名稱,spider 的名稱用于 scrapy 定位爬蟲,所以非常重要,一般常見的名稱方式是使用網(wǎng)站域名(domain),命名 spider,例如 baidu.com 命名為 baidu,但是工作喜歡還是攜帶 .com 后綴。
allowed_domains 屬性:
該屬性需要配置 offsiteMiddleware 使用,當該中間件啟用之后,待采集 URL 的域名如果不在 allowed_domains 列表中,會被禁止訪問。
domains 內容添加,假設你的目標 URL 是 http://www.baidu.com/123.html,僅填寫 baidu.com 即可。
start_urls 屬性:
起始的 URL 列表,主要用于 start_request 方法進行迭代。
custom_settings 屬性:
自定義配置,可以覆蓋 settings.py 的配置,以字典格式賦值。
custom_settings = {
"ROBOTSTXT_OBEY": False # 不請求 robot.txt 文件
}
crawler 屬性:
該屬性在爬蟲啟動后,由類方法 from_crawler() 設置。
settings 屬性:
指定配置文件的實例。
logger 屬性:
spider 日志輸出對象,默認以 spider 名稱創(chuàng)建,可以自定義。
self.logger.info('輸出響應地址 %s', response.url)
logger.info('輸出響應地址 %s', response.url)
補充一下 scrapy 日志級別
在 settings.py 中設置 log 級別,只需要增加一行代碼:
LOG_LEVEL = 'WARNING'
設置為 WARNING 級別,會發(fā)現(xiàn) scrapy 默認的各種調試信息,都不在控制臺輸出。
scrapy 日志級別與 logging 模塊一致。
CRITICAL:嚴重錯誤;
ERROR :一般錯誤;
WARNING: 警告信息;
INFO :一般信息;
DEBUG:調試信息。
在 scrapy 中的 settings 中關于日志的配置如下:
LOG_ENABLED:默認: True,表示啟用 logging;
LOG_ENCODING: 默認: utf-8,logging 使用的編碼;
LOG_FILE 默認: None,日志保存的文件名;
LOG_LEVEL: 默認 DEBUG ,log 的最低級別。
scrapy.Spider 實例方法與類方法
from_crawler 類方法
在查看源碼之后,該方法的功能會比較清晰。
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
spider = cls(*args, **kwargs)
spider._set_crawler(crawler)
return spider
def _set_crawler(self, crawler):
self.crawler = crawler
self.settings = crawler.settings
crawler.signals.connect(self.close, signals.spider_closed)
該方法設置了 crawler 和 settings 兩個屬性,該方法在上一篇博客已經(jīng)有所涉及,直接回顧即可。
parse 方法
當請求(Request)沒有指定回調參數(shù)(callback)時,該方法是 scrapy 用來處理響應的默認回調方法。
log 方法
使用 self.log() 方法記錄日志。
學習到這里,對 Spider 模塊有了一個比較整體的認識。
爬取優(yōu)設網(wǎng)
接下來進入爬蟲采集相關代碼編寫,有了前文知識鋪墊之后,采集代碼就變得非常簡單了。
import scrapy
from uisdc.items import UisdcItem
class UiSpider(scrapy.Spider):
name = 'ui'
allowed_domains = ['www.uisdc.com']
start_urls = ['https://www.uisdc.com/archives']
custom_settings = {
"ROBOTSTXT_OBEY": False
}
def parse(self, response):
# print(response.text)
# self.log("測試是否有數(shù)據(jù)輸出", logging.WARNING)
items = response.xpath('//div[@id="archive_list"]/div/div[1]/div[1]/div[contains(@class,"item-article")]')
for i in items:
item = UisdcItem()
title = i.xpath(".//h2[@class='item-title']/a/text()").extract_first()
author = i.xpath(".//h3[@class='meta-name']/text()").extract_first()
tag = i.xpath(".//div[@class='meta-tag']/a/text()").extract_first()
item["title"] = title
item["author"] = author
item["tag"] = tag
yield item
接下來修改源碼,增加 ** Item Loaders** 填充容器機制。通過 from scrapy.loader import ItemLoader 導入新類,該類的構造函數(shù)如下:
def __init__(self, item=None, selector=None, response=None, parent=None, **context)
其中 item 是容器類,selector 為 Selector 對象,提取填充數(shù)據(jù)的選擇器,response 為 Response 響應對象。
代碼修改之后得到如下代碼:
import scrapy
from uisdc.items import UisdcItem
from scrapy.loader import ItemLoader
class UiSpider(scrapy.Spider):
name = 'ui'
allowed_domains = ['www.uisdc.com']
start_urls = ['https://www.uisdc.com/archives']
custom_settings = {
"ROBOTSTXT_OBEY": False
}
def parse(self, response):
items = response.xpath('//div[@id="archive_list"]/div/div[1]/div[1]/div[contains(@class,"item-article")]')
for i in items:
l = ItemLoader(item=UisdcItem(), selector=i)
l.add_xpath('title', ".//h2[@class='item-title']/a/text()")
l.add_xpath('author', ".//h3[@class='meta-name']/text()")
l.add_xpath('tag', ".//div[@class='meta-tag']/a/text()")
yield l.load_item()
其中需要注意 l = ItemLoader(item=UisdcItem(), selector=i) 使用 selector 參數(shù),并賦值為迭代變量 i,如果使用 response 會得到重復數(shù)據(jù)。
最后,當所有數(shù)據(jù)被收集起來之后, 調用 ItemLoader.load_item() 方法, 返回 Item 對象。
輸出 item 對象,發(fā)現(xiàn)每一個數(shù)據(jù)都是列表。
{'author': ['土撥鼠'],
'tag': ['產品設計'],
'title': ['6000+干貨!資深總監(jiān)的四條產品設計工作觀(附私藏神器包)']}
接下來需要處理每一項的值,ItemLoader 得到的數(shù)據(jù),在存入 item 容器前,是支持對數(shù)據(jù)進行預處理的,即輸入處理器和輸出處理器,修改 items.py 文件。
from scrapy.item import Item, Field
from scrapy.loader.processors import MapCompose, TakeFirst
def ext(value):
return "新聞:" + value
class UisdcItem(Item):
# define the fields for your item here like:
title = Field(
input_processor=MapCompose(ext),
output_processor=TakeFirst()
)
author = Field(output_processor=TakeFirst())
tag = Field(output_processor=TakeFirst())
Field 字段的兩個參數(shù):
輸入處理器(input_processor):可以在傳進來的值做一些預處理。
輸出處理器(output_processor) :輸出值前最后的一步處理。
其中用到了 TakeFirst(),返回第一個非空(non-null/ non-empty)值,常用于單值字段的輸出處理器,無參數(shù)。
還用到了 MapCompose,能把多個函數(shù)執(zhí)行的結果按順序組合起來,產生最終的輸出,通常用于輸入處理器。
其余內置的處理器如下
Identity:不進行任何處理,返回原來的數(shù)據(jù),無參數(shù);
Join:返回用分隔符連接后的值,分隔符默認為空格;
Compose:用給定的多個函數(shù)的組合,來構造處理器,list 對象一次被傳遞到各個函數(shù)中,由最后一個函數(shù)返回整個處理器的輸出,默認情況下遇到 None值(list 中有 None 值)的時候停止處理,可以通過傳遞參數(shù) stop_on_none = False 改變這種行為;
MapCompose:輸入值是被迭代的處理的,List 對象中的每一個元素被單獨傳入,依次執(zhí)行對應函數(shù)。
關于 item loader 還有一些其它的知識點,我們后面再聊。
以上就是python scrapy拆解查看Spider類爬取優(yōu)設網(wǎng)極細講解的詳細內容,更多關于scrapy拆解Spider類爬取優(yōu)設網(wǎng)的資料請關注腳本之家其它相關文章!
- 提升Python Scrapy庫數(shù)據(jù)采集速度實現(xiàn)高效爬蟲
- 詳解如何優(yōu)化和調整Python中Scrapy的性能
- python爬蟲框架scrapy代理中間件掌握學習教程
- python爬蟲框架Scrapy基本應用學習教程
- python實戰(zhàn)項目scrapy管道學習爬取在行高手數(shù)據(jù)
- python實戰(zhàn)scrapy操作cookie爬取博客涉及browsercookie
- python編程scrapy簡單代碼實現(xiàn)搜狗圖片下載器
- Python爬蟲進階Scrapy框架精文講解
- Scrapy基于Python構建強大網(wǎng)絡爬蟲框架實例探究
相關文章
python打印n位數(shù)“水仙花數(shù)”(實例代碼)
這篇文章主要介紹了python打印n位數(shù)“水仙花數(shù)”,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12
一篇文章教你掌握python數(shù)據(jù)類型的底層實現(xiàn)
這篇文章主要介紹了Python 數(shù)據(jù)類型的底層實現(xiàn)原理分析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-09-09
Python如何基于Tesseract實現(xiàn)識別文字功能
這篇文章主要介紹了Python如何基于Tesseract實現(xiàn)識別文字功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
Python3實現(xiàn)的簡單工資管理系統(tǒng)示例
這篇文章主要介紹了Python3實現(xiàn)的簡單工資管理系統(tǒng),涉及Python文件讀寫、數(shù)據(jù)遍歷、判斷等相關操作技巧,需要的朋友可以參考下2019-03-03
python 阿里云oss實現(xiàn)直傳簽名與回調驗證的示例方法
這篇文章主要介紹了python 阿里云oss實現(xiàn)直傳簽名與回調驗證,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03

