- Scrapy 教程
- Scrapy - 首頁
- Scrapy 基本概念
- Scrapy - 概述
- Scrapy - 環境
- Scrapy - 命令列工具
- Scrapy - 爬蟲
- Scrapy - 選擇器
- Scrapy - 專案
- Scrapy - 專案載入器
- Scrapy - Shell
- Scrapy - 專案管道
- Scrapy - 資料匯出
- Scrapy - 請求 & 響應
- Scrapy - 連結提取器
- Scrapy - 設定
- Scrapy - 異常
- Scrapy 實戰專案
- Scrapy - 建立專案
- Scrapy - 定義專案
- Scrapy - 第一個爬蟲
- Scrapy - 爬取
- Scrapy - 提取專案
- Scrapy - 使用專案
- Scrapy - 跟蹤連結
- Scrapy - 爬取資料
- Scrapy 有用資源
- Scrapy - 快速指南
- Scrapy - 有用資源
- Scrapy - 討論
Scrapy - 快速指南
Scrapy - 概述
Scrapy 是一個用 Python 編寫的快速、開源的網頁爬取框架,用於利用基於 XPath 的選擇器從網頁中提取資料。
Scrapy 於 2008 年 6 月 26 日首次釋出,獲得 BSD 許可,並在 2015 年 6 月釋出了 1.0 版本里程碑。
為什麼要使用 Scrapy?
構建和擴充套件大型爬取專案更容易。
它有一個名為選擇器的內建機制,用於從網站提取資料。
它非同步處理請求並且速度很快。
它使用 自動限速機制 自動調整爬取速度。
確保開發者可訪問性。
Scrapy 的特性
Scrapy 是一個開源且免費使用的網頁爬取框架。
Scrapy 生成以 JSON、CSV 和 XML 等格式的資料匯出。
Scrapy 內建支援透過 XPath 或 CSS 表示式從源選擇和提取資料。
基於爬蟲的 Scrapy 允許自動從網頁中提取資料。
優點
Scrapy 易於擴充套件,快速且強大。
它是一個跨平臺應用程式框架(Windows、Linux、Mac OS 和 BSD)。
Scrapy 請求被非同步排程和處理。
Scrapy 帶有一個名為 Scrapyd 的內建服務,允許使用 JSON Web 服務上傳專案和控制爬蟲。
即使網站沒有用於原始資料訪問的 API,也可以抓取任何網站。
缺點
Scrapy 僅適用於 Python 2.7 及以上版本。
不同作業系統的安裝方式不同。
Scrapy - 環境
在本章中,我們將討論如何安裝和設定 Scrapy。Scrapy 必須與 Python 一起安裝。
Scrapy 可以使用 pip 安裝。要安裝,請執行以下命令:
pip install Scrapy
Windows
注意 - Windows 作業系統不支援 Python 3。
步驟 1 - 從 Python 安裝 Python 2.7
透過將以下路徑新增到 PATH 來設定環境變數:
C:\Python27\;C:\Python27\Scripts\;
可以使用以下命令檢查 Python 版本:
python --version
步驟 2 - 安裝 OpenSSL。
在環境變數中新增 C:\OpenSSL-Win32\bin。
注意 - 除 Windows 外,所有作業系統都預裝了 OpenSSL。
步驟 3 - 安裝 Visual C++ 2008 可再發行元件。
步驟 4 - 安裝 pywin32。
步驟 5 - 為低於 2.7.9 的 Python 版本安裝 pip。
可以使用以下命令檢查 pip 版本:
pip --version
步驟 6 - 要安裝 scrapy,請執行以下命令:
pip install Scrapy
Anaconda
如果您的機器上安裝了 anaconda 或 miniconda,請執行以下命令使用 conda 安裝 Scrapy:
conda install -c scrapinghub scrapy
Scrapinghub 公司支援 Linux、Windows 和 OS X 的官方 conda 包。
注意 - 如果您在透過 pip 安裝時遇到問題,建議使用上述命令安裝 Scrapy。
Ubuntu 9.10 或更高版本
Ubuntu 作業系統預裝了最新版本的 Python。使用 Scrapinghub 提供的 Ubuntu 包 aptgettable。要使用這些包:
步驟 1 - 您需要將用於簽署 Scrapy 包的 GPG 金鑰匯入到 APT 金鑰環中:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 627220E7
步驟 2 - 接下來,使用以下命令建立 /etc/apt/sources.list.d/scrapy.list 檔案:
echo 'deb http://archive.scrapy.org/ubuntu scrapy main' | sudo tee /etc/apt/sources.list.d/scrapy.list
步驟 3 - 更新包列表並安裝 scrapy:
sudo apt-get update && sudo apt-get install scrapy
Archlinux
您可以使用以下命令從 AUR Scrapy 包安裝 Scrapy:
yaourt -S scrapy
Mac OS X
使用以下命令安裝 Xcode 命令列工具:
xcode-select --install
不要使用系統 Python,而是安裝一個新的更新版本,以免與系統其他部分衝突。
步驟 1 - 安裝 homebrew。
步驟 2 - 設定環境 PATH 變數以指定在使用系統包之前應使用 homebrew 包:
echo "export PATH = /usr/local/bin:/usr/local/sbin:$PATH" >> ~/.bashrc
步驟 3 - 為了確保更改已完成,請使用以下命令重新載入 .bashrc:
source ~/.bashrc
步驟 4 - 接下來,使用以下命令安裝 Python:
brew install python
步驟 5 - 使用以下命令安裝 Scrapy:
pip install Scrapy
Scrapy - 命令列工具
描述
Scrapy 命令列工具用於控制 Scrapy,通常稱為 'Scrapy 工具'。它包含用於各種物件的命令,以及一組引數和選項。
配置設定
Scrapy 將在 scrapy.cfg 檔案中查詢配置設定。以下是一些位置:
系統中的 C:\scrapy(專案資料夾)\scrapy.cfg
全域性設定的 ~/.config/scrapy.cfg ($XDG_CONFIG_HOME) 和 ~/.scrapy.cfg ($HOME)
您可以在專案的根目錄中找到 scrapy.cfg。
Scrapy 也可以使用以下環境變數進行配置:
- SCRAPY_SETTINGS_MODULE
- SCRAPY_PROJECT
- SCRAPY_PYTHON_SHELL
Scrapy 專案的預設結構
以下結構顯示了 Scrapy 專案的預設檔案結構。
scrapy.cfg - Deploy the configuration file
project_name/ - Name of the project
_init_.py
items.py - It is project's items file
pipelines.py - It is project's pipelines file
settings.py - It is project's settings file
spiders - It is the spiders directory
_init_.py
spider_name.py
. . .
scrapy.cfg 檔案是專案根目錄,其中包含專案名稱和專案設定。例如:
[settings] default = [name of the project].settings [deploy] #url = https://:6800/ project = [name of the project]
使用 Scrapy 工具
Scrapy 工具提供了一些用法和可用的命令,如下所示:
Scrapy X.Y - no active project Usage: scrapy [options] [arguments] Available commands: crawl It puts spider (handle the URL) to work for crawling data fetch It fetches the response from the given URL
建立專案
您可以使用以下命令在 Scrapy 中建立專案:
scrapy startproject project_name
這將建立名為 project_name 的專案目錄。接下來,使用以下命令轉到新建立的專案:
cd project_name
控制專案
您可以使用 Scrapy 工具控制專案並對其進行管理,還可以使用以下命令建立新的爬蟲:
scrapy genspider mydomain mydomain.com
諸如 crawl 等命令必須在 Scrapy 專案內部使用。在接下來的部分中,您將瞭解哪些命令必須在 Scrapy 專案內部執行。
Scrapy 包含一些內建命令,可用於您的專案。要檢視可用命令的列表,請使用以下命令:
scrapy -h
當您執行以下命令時,Scrapy 將顯示可用命令的列表,如下所示:
fetch - 它使用 Scrapy 下載器獲取 URL。
runspider - 用於執行自包含的爬蟲,無需建立專案。
settings - 它指定專案設定值。
shell - 它是給定 URL 的互動式抓取模組。
startproject - 建立一個新的 Scrapy 專案。
version - 顯示 Scrapy 版本。
view - 它使用 Scrapy 下載器獲取 URL,並在瀏覽器中顯示內容。
您還可以使用一些與專案相關的命令,如下所示:
crawl - 用於使用爬蟲爬取資料。
check - 檢查爬取命令返回的專案。
list - 顯示專案中所有可用爬蟲的列表。
edit - 您可以使用編輯器編輯爬蟲。
parse - 使用爬蟲解析給定的 URL。
bench - 用於執行快速基準測試(基準測試告訴 Scrapy 每分鐘可以爬取多少個頁面)。
自定義專案命令
您可以使用 Scrapy 專案中的 COMMANDS_MODULE 設定構建自定義專案命令。它包含設定中的一個預設空字串。您可以新增以下自定義命令:
COMMANDS_MODULE = 'mycmd.commands'
Scrapy 命令可以透過 setup.py 檔案中的 scrapy.commands 部分新增,如下所示:
from setuptools import setup, find_packages
setup(name = 'scrapy-module_demo',
entry_points = {
'scrapy.commands': [
'cmd_demo = my_module.commands:CmdDemo',
],
},
)
以上程式碼在 setup.py 檔案中添加了 cmd_demo 命令。
Scrapy - 爬蟲
描述
爬蟲是一個類,負責定義如何透過網站跟蹤連結並從頁面中提取資訊。
Scrapy 的預設爬蟲如下:
scrapy.Spider
它是一個爬蟲,所有其他爬蟲都必須繼承它。它具有以下類:
class scrapy.spiders.Spider
下表顯示了 scrapy.Spider 類的欄位:
| 序號 | 欄位 & 描述 |
|---|---|
| 1 | name 它是您的爬蟲的名稱。 |
| 2 | allowed_domains 它是爬蟲爬取的域名的列表。 |
| 3 | start_urls 它是 URL 列表,將成為後續爬取的根,爬蟲將從此處開始爬取。 |
| 4 | 自定義設定 這些是在執行爬蟲時,會覆蓋專案全域性配置的設定。 |
| 5 | 爬蟲 它是一個屬性,連結到爬蟲例項繫結的 Crawler 物件。 |
| 6 | 設定 這些是執行爬蟲的設定。 |
| 7 | 日誌記錄器 它是一個 Python 日誌記錄器,用於傳送日誌訊息。 |
| 8 | from_crawler(crawler,*args,**kwargs) 它是一個類方法,用於建立你的爬蟲。引數如下:
|
| 9 | start_requests() 當沒有指定特定的 URL 且爬蟲開啟進行抓取時,Scrapy 會呼叫 start_requests() 方法。 |
| 10 | make_requests_from_url(url) 它是一個用於將 URL 轉換為請求的方法。 |
| 11 | parse(response) 此方法處理響應並返回抓取的資料,以及更多 URL。 |
| 12 | log(message[,level,component]) 它是一個透過爬蟲日誌記錄器傳送日誌訊息的方法。 |
| 13 | closed(reason) 當爬蟲關閉時,會呼叫此方法。 |
爬蟲引數
爬蟲引數用於指定起始 URL,並使用 crawl 命令以及 -a 選項傳遞,如下所示:
scrapy crawl first_scrapy -a group = accessories
以下程式碼演示了爬蟲如何接收引數:
import scrapy
class FirstSpider(scrapy.Spider):
name = "first"
def __init__(self, group = None, *args, **kwargs):
super(FirstSpider, self).__init__(*args, **kwargs)
self.start_urls = ["http://www.example.com/group/%s" % group]
通用爬蟲
您可以使用通用爬蟲從其子類化您的爬蟲。它們的目的是根據某些規則遵循網站上的所有連結,以從所有頁面提取資料。
對於以下爬蟲中使用的示例,讓我們假設我們有一個具有以下欄位的專案:
import scrapy from scrapy.item import Item, Field class First_scrapyItem(scrapy.Item): product_title = Field() product_link = Field() product_description = Field()
CrawlSpider
CrawlSpider 定義了一組規則來遵循連結並抓取多個頁面。它具有以下類:
class scrapy.spiders.CrawlSpider
以下是 CrawlSpider 類的屬性:
rules
它是一個規則物件的列表,定義了爬蟲如何遵循連結。
下表顯示了 CrawlSpider 類的規則:
| 序號 | 規則 & 描述 |
|---|---|
| 1 | LinkExtractor 它指定了爬蟲如何遵循連結並提取資料。 |
| 2 | callback 在每個頁面被抓取後呼叫。 |
| 3 | follow 它指定是否繼續遵循連結。 |
parse_start_url(response)
它透過允許解析初始響應來返回專案或請求物件。
注意 − 確保在編寫規則時將 parse 函式重新命名為除 parse 之外的其他名稱,因為 parse 函式由 CrawlSpider 用於實現其邏輯。
讓我們看下面的例子,其中爬蟲從 demoexample.com 的主頁開始爬取,收集所有頁面、連結,並使用 parse_items 方法進行解析:
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class DemoSpider(CrawlSpider):
name = "demo"
allowed_domains = ["www.demoexample.com"]
start_urls = ["http://www.demoexample.com"]
rules = (
Rule(LinkExtractor(allow =(), restrict_xpaths = ("//div[@class = 'next']",)),
callback = "parse_item", follow = True),
)
def parse_item(self, response):
item = DemoItem()
item["product_title"] = response.xpath("a/text()").extract()
item["product_link"] = response.xpath("a/@href").extract()
item["product_description"] = response.xpath("div[@class = 'desc']/text()").extract()
return items
XMLFeedSpider
它是用於從 XML 提要抓取並迭代節點的爬蟲的基類。它具有以下類:
class scrapy.spiders.XMLFeedSpider
下表顯示了用於設定迭代器和標籤名稱的類屬性:
| 序號 | 屬性 & 描述 |
|---|---|
| 1 | iterator 它定義了要使用的迭代器。它可以是 iternodes、html 或 xml。預設值為 iternodes。 |
| 2 | itertag 它是一個包含要迭代的節點名稱的字串。 |
| 3 | namespaces 它由 (字首,uri) 元組列表定義,這些元組使用 register_namespace() 方法自動註冊名稱空間。 |
| 4 | adapt_response(response) 它接收響應並在響應體從爬蟲中介軟體到達後立即修改它,在爬蟲開始解析它之前。 |
| 5 | parse_node(response,selector) 當為每個匹配提供的標籤名稱的節點呼叫時,它接收響應和選擇器。 注意 − 如果您不覆蓋此方法,您的爬蟲將無法工作。 |
| 6 | process_results(response,results) 它返回爬蟲返回的結果和響應列表。 |
CSVFeedSpider
它迭代其每一行,接收 CSV 檔案作為響應,並呼叫 parse_row() 方法。它具有以下類:
class scrapy.spiders.CSVFeedSpider
下表顯示了關於 CSV 檔案可以設定的選項:
| 序號 | 選項 & 描述 |
|---|---|
| 1 | delimiter 它是一個包含逗號 (,) 分隔符的字串,用於每個欄位。 |
| 2 | quotechar 它是一個包含引號 (“) 的字串,用於每個欄位。 |
| 3 | headers 它是一個語句列表,從中可以提取欄位。 |
| 4 | parse_row(response,row) 它接收響應和每一行以及標題的鍵。 |
CSVFeedSpider 示例
from scrapy.spiders import CSVFeedSpider
from demoproject.items import DemoItem
class DemoSpider(CSVFeedSpider):
name = "demo"
allowed_domains = ["www.demoexample.com"]
start_urls = ["http://www.demoexample.com/feed.csv"]
delimiter = ";"
quotechar = "'"
headers = ["product_title", "product_link", "product_description"]
def parse_row(self, response, row):
self.logger.info("This is row: %r", row)
item = DemoItem()
item["product_title"] = row["product_title"]
item["product_link"] = row["product_link"]
item["product_description"] = row["product_description"]
return item
SitemapSpider
SitemapSpider 透過從 robots.txt 中找到 URL 來幫助 網站地圖 爬取網站。它具有以下類:
class scrapy.spiders.SitemapSpider
下表顯示了 SitemapSpider 的欄位:
| 序號 | 欄位 & 描述 |
|---|---|
| 1 | sitemap_urls 您要爬取的指向網站地圖的 URL 列表。 |
| 2 | sitemap_rules 它是一個 (正則表示式,回撥) 元組列表,其中正則表示式是一個正則表示式,回撥用於處理與正則表示式匹配的 URL。 |
| 3 | sitemap_follow 它是要遵循的網站地圖正則表示式列表。 |
| 4 | sitemap_alternate_links 指定要為單個 URL 遵循的備用連結。 |
SitemapSpider 示例
以下 SitemapSpider 處理所有 URL:
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider):
urls = ["http://www.demoexample.com/sitemap.xml"]
def parse(self, response):
# You can scrap items here
以下 SitemapSpider 使用回撥處理一些 URL:
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider):
urls = ["http://www.demoexample.com/sitemap.xml"]
rules = [
("/item/", "parse_item"),
("/group/", "parse_group"),
]
def parse_item(self, response):
# you can scrap item here
def parse_group(self, response):
# you can scrap group here
以下程式碼顯示了 robots.txt 中的網站地圖,其 url 包含 /sitemap_company:
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider):
urls = ["http://www.demoexample.com/robots.txt"]
rules = [
("/company/", "parse_company"),
]
sitemap_follow = ["/sitemap_company"]
def parse_company(self, response):
# you can scrap company here
您甚至可以將 SitemapSpider 與其他 URL 結合使用,如下面的命令所示。
from scrapy.spiders import SitemapSpider
class DemoSpider(SitemapSpider):
urls = ["http://www.demoexample.com/robots.txt"]
rules = [
("/company/", "parse_company"),
]
other_urls = ["http://www.demoexample.com/contact-us"]
def start_requests(self):
requests = list(super(DemoSpider, self).start_requests())
requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]
return requests
def parse_company(self, response):
# you can scrap company here...
def parse_other(self, response):
# you can scrap other here...
Scrapy - 選擇器
描述
當您抓取網頁時,您需要使用稱為選擇器的機制來提取 HTML 原始碼的特定部分,這可以透過使用 XPath 或 CSS 表示式來實現。選擇器建立在lxml庫之上,該庫使用 Python 語言處理 XML 和 HTML。
使用以下程式碼片段來定義選擇器的不同概念:
<html>
<head>
<title>My Website</title>
</head>
<body>
<span>Hello world!!!</span>
<div class = 'links'>
<a href = 'one.html'>Link 1<img src = 'image1.jpg'/></a>
<a href = 'two.html'>Link 2<img src = 'image2.jpg'/></a>
<a href = 'three.html'>Link 3<img src = 'image3.jpg'/></a>
</div>
</body>
</html>
構造選擇器
您可以透過傳遞文字或TextResponse物件來構造選擇器類例項。根據提供的輸入型別,選擇器選擇以下規則:
from scrapy.selector import Selector from scrapy.http import HtmlResponse
使用上述程式碼,您可以從文字中構造如下:
Selector(text = body).xpath('//span/text()').extract()
它將顯示結果如下:
[u'Hello world!!!']
您可以從響應中構造如下:
response = HtmlResponse(url = 'http://mysite.com', body = body)
Selector(response = response).xpath('//span/text()').extract()
它將顯示結果如下:
[u'Hello world!!!']
使用選擇器
使用上述簡單的程式碼片段,您可以構建 XPath 以選擇在標題標籤中定義的文字,如下所示:
>>response.selector.xpath('//title/text()')
現在,您可以使用.extract()方法提取文字資料,如下所示:
>>response.xpath('//title/text()').extract()
它將產生以下結果:
[u'My Website']
您可以顯示所有元素的名稱,如下所示:
>>response.xpath('//div[@class = "links"]/a/text()').extract()
它將顯示以下元素:
Link 1 Link 2 Link 3
如果要提取第一個元素,則使用.extract_first()方法,如下所示:
>>response.xpath('//div[@class = "links"]/a/text()').extract_first()
它將顯示以下元素:
Link 1
巢狀選擇器
使用上述程式碼,您可以巢狀選擇器以使用.xpath()方法顯示頁面連結和影像源,如下所示:
links = response.xpath('//a[contains(@href, "image")]')
for index, link in enumerate(links):
args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract())
print 'The link %d pointing to url %s and image %s' % args
它將顯示結果如下:
Link 1 pointing to url [u'one.html'] and image [u'image1.jpg'] Link 2 pointing to url [u'two.html'] and image [u'image2.jpg'] Link 3 pointing to url [u'three.html'] and image [u'image3.jpg']
使用正則表示式的選擇器
Scrapy 允許使用正則表示式提取資料,它使用.re()方法。從上面的 HTML 程式碼中,我們將提取影像名稱,如下所示:
>>response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:\s*(.*)')
以上程式碼行顯示影像名稱如下:
[u'Link 1', u'Link 2', u'Link 3']
使用相對 XPath
當您使用以/開頭的 XPath 時,巢狀選擇器和 XPath 與文件的絕對路徑相關,而不是選擇器的相對路徑。
如果要提取<p>元素,則首先獲取所有 div 元素:
>>mydiv = response.xpath('//div')
接下來,您可以透過在 XPath 前新增點作為.//p來提取內部的所有'p'元素,如下所示:
>>for p in mydiv.xpath('.//p').extract()
使用 EXSLT 擴充套件
EXSLT 是一個社群,它釋出了對 XSLT(可擴充套件樣式表語言轉換)的擴充套件,該轉換將 XML 文件轉換為 XHTML 文件。您可以使用 XPath 表示式中註冊的名稱空間來使用 EXSLT 擴充套件,如下表所示:
| 序號 | 字首 & 用途 | 名稱空間 |
|---|---|---|
| 1 | re 正則表示式 |
|
| 2 | set 集合操作 |
您可以在上一節中檢視使用正則表示式提取資料的簡單程式碼格式。
有一些 XPath 提示,在將 XPath 與 Scrapy 選擇器一起使用時非常有用。有關更多資訊,請點選此 連結。
Scrapy - 專案
描述
Scrapy 程序可用於從諸如網頁之類的源提取資料,使用爬蟲。Scrapy 使用Item類生成輸出,其物件用於收集抓取的資料。
宣告專案
您可以使用類定義語法以及欄位物件來宣告專案,如下所示:
import scrapy class MyProducts(scrapy.Item): productName = Field() productLink = Field() imageURL = Field() price = Field() size = Field()
專案欄位
專案欄位用於顯示每個欄位的元資料。由於欄位物件上的值沒有限制,因此可訪問的元資料鍵不包含任何元資料參考列表。欄位物件用於指定所有欄位元資料,並且您可以根據專案的要求指定任何其他欄位鍵。可以使用 Item.fields 屬性訪問欄位物件。
使用專案
當您使用專案時,可以定義一些常見函式。有關更多資訊,請點選此 連結。
擴充套件專案
可以透過宣告原始專案的子類來擴充套件專案。例如:
class MyProductDetails(Product): original_rate = scrapy.Field(serializer = str) discount_rate = scrapy.Field()
您可以使用現有的欄位元資料透過新增更多值或更改現有值來擴充套件欄位元資料,如下面的程式碼所示:
class MyProductPackage(Product): name = scrapy.Field(Product.fields['name'], serializer = serializer_demo)
專案物件
專案物件可以使用以下類來指定,該類根據給定的引數提供新的初始化專案:
class scrapy.item.Item([arg])
Item 提供建構函式的副本,並提供一個額外的屬性,該屬性由欄位中的專案給出。
欄位物件
欄位物件可以使用以下類來指定,其中 Field 類不發出其他過程或屬性:
class scrapy.item.Field([arg])
Scrapy - 專案載入器
描述
專案載入器提供了一種方便的方法來填充從網站抓取的專案。
宣告專案載入器
專案載入器的宣告類似於專案。
例如:
from scrapy.loader import ItemLoader from scrapy.loader.processors import TakeFirst, MapCompose, Join class DemoLoader(ItemLoader): default_output_processor = TakeFirst() title_in = MapCompose(unicode.title) title_out = Join() size_in = MapCompose(unicode.strip) # you can continue scraping here
在上面的程式碼中,您可以看到輸入處理器使用_in字尾宣告,輸出處理器使用_out字尾宣告。
ItemLoader.default_input_processor和ItemLoader.default_output_processor屬性用於宣告預設輸入/輸出處理器。
使用 Item Loaders 填充 Item
要使用 Item Loader,首先需要使用類似字典的物件或不使用任何物件例項化它,其中 Item 使用在ItemLoader.default_item_class屬性中指定的 Item 類。
您可以使用選擇器將值收集到 Item Loader 中。
您可以在同一 Item 欄位中新增更多值,Item Loader 將使用適當的處理器來新增這些值。
以下程式碼演示瞭如何使用 Item Loaders 填充 Item:
from scrapy.loader import ItemLoader
from demoproject.items import Demo
def parse(self, response):
l = ItemLoader(item = Product(), response = response)
l.add_xpath("title", "//div[@class = 'product_title']")
l.add_xpath("title", "//div[@class = 'product_name']")
l.add_xpath("desc", "//div[@class = 'desc']")
l.add_css("size", "div#size]")
l.add_value("last_updated", "yesterday")
return l.load_item()
如上所示,有兩個不同的 XPath 用於提取title欄位,使用add_xpath()方法提取:
1. //div[@class = "product_title"]
2. //div[@class = "product_name"]
然後,對desc欄位使用類似的請求。尺寸資料使用add_css()方法提取,last_updated使用add_value()方法填充值為“yesterday”。
收集完所有資料後,呼叫ItemLoader.load_item()方法,該方法返回使用add_xpath()、add_css()和add_value()方法提取資料填充的 Item。
輸入和輸出處理器
Item Loader 的每個欄位包含一個輸入處理器和一個輸出處理器。
提取資料時,輸入處理器會處理它,並將結果儲存在 ItemLoader 中。
接下來,在收集完資料後,呼叫 ItemLoader.load_item() 方法以獲取填充的 Item 物件。
最後,您可以將輸出處理器的結果分配給 Item。
以下程式碼演示瞭如何為特定欄位呼叫輸入和輸出處理器:
l = ItemLoader(Product(), some_selector)
l.add_xpath("title", xpath1) # [1]
l.add_xpath("title", xpath2) # [2]
l.add_css("title", css) # [3]
l.add_value("title", "demo") # [4]
return l.load_item() # [5]
第 1 行 - 從 xpath1 提取 title 的資料,並透過輸入處理器傳遞,並將結果收集並存儲在 ItemLoader 中。
第 2 行 - 同樣,從 xpath2 提取 title,並透過相同的輸入處理器傳遞,並將結果新增到為 [1] 收集的資料中。
第 3 行 - 從 css 選擇器提取 title,並透過相同的輸入處理器傳遞,並將結果新增到為 [1] 和 [2] 收集的資料中。
第 4 行 - 接下來,分配值“demo”並透過輸入處理器傳遞。
第 5 行 - 最後,從所有欄位內部收集資料並傳遞給輸出處理器,並將最終值分配給 Item。
宣告輸入和輸出處理器
輸入和輸出處理器在 ItemLoader 定義中宣告。除此之外,它們也可以在Item 欄位元資料中指定。
例如:
import scrapy
from scrapy.loader.processors import Join, MapCompose, TakeFirst
from w3lib.html import remove_tags
def filter_size(value):
if value.isdigit():
return value
class Item(scrapy.Item):
name = scrapy.Field(
input_processor = MapCompose(remove_tags),
output_processor = Join(),
)
size = scrapy.Field(
input_processor = MapCompose(remove_tags, filter_price),
output_processor = TakeFirst(),
)
>>> from scrapy.loader import ItemLoader
>>> il = ItemLoader(item = Product())
>>> il.add_value('title', [u'Hello', u'<strong>world</strong>'])
>>> il.add_value('size', [u'<span>100 kg</span>'])
>>> il.load_item()
它顯示輸出為:
{'title': u'Hello world', 'size': u'100 kg'}
Item Loader 上下文
Item Loader 上下文是一個字典,其中包含在輸入和輸出處理器之間共享的任意鍵值。
例如,假設您有一個函式parse_length:
def parse_length(text, loader_context):
unit = loader_context.get('unit', 'cm')
# You can write parsing code of length here
return parsed_length
透過接收 loader_context 引數,它告訴 Item Loader 它可以接收 Item Loader 上下文。有幾種方法可以更改 Item Loader 上下文的值:
修改當前活動的 Item Loader 上下文:
loader = ItemLoader (product) loader.context ["unit"] = "mm"
在 Item Loader 例項化時:
loader = ItemLoader(product, unit = "mm")
在為使用 Item Loader 上下文例項化的輸入/輸出處理器宣告 Item Loader 時:
class ProductLoader(ItemLoader): length_out = MapCompose(parse_length, unit = "mm")
ItemLoader 物件
它是一個物件,它返回一個新的 Item Loader 來填充給定的 Item。它具有以下類:
class scrapy.loader.ItemLoader([item, selector, response, ]**kwargs)
下表顯示了 ItemLoader 物件的引數:
| 序號 | 引數及描述 |
|---|---|
| 1 | item 它是透過呼叫 add_xpath()、add_css() 或 add_value() 來填充的 Item。 |
| 2 | selector 它用於從網站提取資料。 |
| 3 | response 它用於使用 default_selector_class 構造選擇器。 |
下表顯示了 ItemLoader 物件的方法:
| 序號 | 方法及描述 | 示例 |
|---|---|---|
| 1 | get_value(value, *processors, **kwargs) 透過給定的處理器和關鍵字引數,get_value() 方法處理該值。 |
>>> from scrapy.loader.processors import TakeFirst >>> loader.get_value(u'title: demoweb', TakeFirst(), unicode.upper, re = 'title: (.+)') 'DEMOWEB` |
| 2 | add_value(field_name, value, *processors, **kwargs) 它處理該值並將其新增到欄位中,在傳遞給欄位輸入處理器之前,先透過提供處理器和關鍵字引數將其傳遞給 get_value。 |
loader.add_value('title', u'DVD')
loader.add_value('colors', [u'black', u'white'])
loader.add_value('length', u'80')
loader.add_value('price', u'2500')
|
| 3 | replace_value(field_name, value, *processors, **kwargs) 它用新值替換收集到的資料。 |
loader.replace_value('title', u'DVD')
loader.replace_value('colors', [u'black',
u'white'])
loader.replace_value('length', u'80')
loader.replace_value('price', u'2500')
|
| 4 | get_xpath(xpath, *processors, **kwargs) 它用於透過提供處理器和關鍵字引數來提取 Unicode 字串,並接收XPath。 |
# HTML code: <div class = "item-name">DVD</div>
loader.get_xpath("//div[@class =
'item-name']")
# HTML code: <div id = "length">the length is
45cm</div>
loader.get_xpath("//div[@id = 'length']", TakeFirst(),
re = "the length is (.*)")
|
| 5 | add_xpath(field_name, xpath, *processors, **kwargs) 它接收XPath到提取 Unicode 字串的欄位。 |
# HTML code: <div class = "item-name">DVD</div>
loader.add_xpath('name', '//div
[@class = "item-name"]')
# HTML code: <div id = "length">the length is
45cm</div>
loader.add_xpath('length', '//div[@id = "length"]',
re = 'the length is (.*)')
|
| 6 | replace_xpath(field_name, xpath, *processors, **kwargs) 它使用網站上的XPath替換收集到的資料。 |
# HTML code: <div class = "item-name">DVD</div>
loader.replace_xpath('name', '
//div[@class = "item-name"]')
# HTML code: <div id = "length">the length is
45cm</div>
loader.replace_xpath('length', '
//div[@id = "length"]', re = 'the length is (.*)')
|
| 7 | get_css(css, *processors, **kwargs) 它接收用於提取 Unicode 字串的 CSS 選擇器。 |
loader.get_css("div.item-name")
loader.get_css("div#length", TakeFirst(),
re = "the length is (.*)")
|
| 8 | add_css(field_name, css, *processors, **kwargs) 它類似於 add_value() 方法,區別在於它將 CSS 選擇器新增到欄位中。 |
loader.add_css('name', 'div.item-name')
loader.add_css('length', 'div#length',
re = 'the length is (.*)')
|
| 9 | replace_css(field_name, css, *processors, **kwargs) 它使用 CSS 選擇器替換提取的資料。 |
loader.replace_css('name', 'div.item-name')
loader.replace_css('length', 'div#length',
re = 'the length is (.*)')
|
| 10 | load_item() 收集完資料後,此方法使用收集到的資料填充 Item 並返回它。 |
def parse(self, response):
l = ItemLoader(item = Product(),
response = response)
l.add_xpath('title', '//
div[@class = "product_title"]')
loader.load_item()
|
| 11 | nested_xpath(xpath) 它用於使用 XPath 選擇器建立巢狀載入器。 |
loader = ItemLoader(item = Item())
loader.add_xpath('social', '
a[@class = "social"]/@href')
loader.add_xpath('email', '
a[@class = "email"]/@href')
|
| 12 | nested_css(css) 它用於使用 CSS 選擇器建立巢狀載入器。 |
loader = ItemLoader(item = Item())
loader.add_css('social', 'a[@class = "social"]/@href')
loader.add_css('email', 'a[@class = "email"]/@href')
|
下表顯示了 ItemLoader 物件的屬性:
| 序號 | 屬性 & 描述 |
|---|---|
| 1 | item 它是 Item Loader 執行解析的物件。 |
| 2 | context 它是當前活動的 Item Loader 的上下文。 |
| 3 | default_item_class 它用於表示 Item,如果在建構函式中未給出。 |
| 4 | default_input_processor 僅對未指定輸入處理器的欄位使用 default_input_processors。 |
| 5 | default_output_processor 僅對未指定輸出處理器的欄位使用 default_output_processors。 |
| 6 | default_selector_class 它是一個用於構造選擇器的類,如果在建構函式中未給出。 |
| 7 | selector 它是一個可以用來從網站提取資料的物件。 |
巢狀載入器
它用於在從文件的子部分解析值時建立巢狀載入器。如果您不建立巢狀載入器,則需要為要提取的每個值指定完整的 XPath 或 CSS。
例如,假設資料是從標題頁面提取的:
<header> <a class = "social" href = "http://facebook.com/whatever">facebook</a> <a class = "social" href = "http://twitter.com/whatever">twitter</a> <a class = "email" href = "mailto:someone@example.com">send mail</a> </header>
接下來,您可以透過向標題新增相關值來使用標題選擇器建立巢狀載入器:
loader = ItemLoader(item = Item())
header_loader = loader.nested_xpath('//header')
header_loader.add_xpath('social', 'a[@class = "social"]/@href')
header_loader.add_xpath('email', 'a[@class = "email"]/@href')
loader.load_item()
重用和擴充套件 Item Loaders
Item Loaders 旨在減輕維護工作,當您的專案獲取更多爬蟲時,這會成為一個基本問題。
例如,假設一個網站將其產品名稱用三個短劃線括起來(例如 --DVD---)。如果您不希望在最終的產品名稱中包含這些短劃線,則可以使用預設的 Product Item Loader 來刪除它們,如下面的程式碼所示:
from scrapy.loader.processors import MapCompose
from demoproject.ItemLoaders import DemoLoader
def strip_dashes(x):
return x.strip('-')
class SiteSpecificLoader(DemoLoader):
title_in = MapCompose(strip_dashes, DemoLoader.title_in)
可用的內建處理器
以下是一些常用的內建處理器:
class scrapy.loader.processors.Identity
它返回原始值而不更改它。例如:
>>> from scrapy.loader.processors import Identity >>> proc = Identity() >>> proc(['a', 'b', 'c']) ['a', 'b', 'c']
class scrapy.loader.processors.TakeFirst
它返回從接收到的值列表中第一個非空/非 null 的值。例如:
>>> from scrapy.loader.processors import TakeFirst >>> proc = TakeFirst() >>> proc(['', 'a', 'b', 'c']) 'a'
class scrapy.loader.processors.Join(separator = u' ')
它返回附加到分隔符的值。預設分隔符為 u' ',它等效於函式u' '.join。例如:
>>> from scrapy.loader.processors import Join
>>> proc = Join()
>>> proc(['a', 'b', 'c'])
u'a b c'
>>> proc = Join('<br>')
>>> proc(['a', 'b', 'c'])
u'a<br>b<br>c'
class scrapy.loader.processors.Compose(*functions, **default_loader_context)
它由一個處理器定義,其中其每個輸入值都傳遞給第一個函式,該函式的結果傳遞給第二個函式,依此類推,直到最後一個函式返回最終值作為輸出。
例如:
>>> from scrapy.loader.processors import Compose >>> proc = Compose(lambda v: v[0], str.upper) >>> proc(['python', 'scrapy']) 'PYTHON'
class scrapy.loader.processors.MapCompose(*functions, **default_loader_context)
它是一個處理器,其中輸入值被迭代,並且第一個函式應用於每個元素。接下來,這些函式呼叫的結果被連線起來以構建新的可迭代物件,然後將其應用於第二個函式,依此類推,直到最後一個函式。
例如:
>>> def filter_scrapy(x): return None if x == 'scrapy' else x >>> from scrapy.loader.processors import MapCompose >>> proc = MapCompose(filter_scrapy, unicode.upper) >>> proc([u'hi', u'everyone', u'im', u'pythonscrapy']) [u'HI, u'IM', u'PYTHONSCRAPY']
class scrapy.loader.processors.SelectJmes(json_path)
此類使用提供的 json 路徑查詢值並返回輸出。
例如:
>>> from scrapy.loader.processors import SelectJmes, Compose, MapCompose
>>> proc = SelectJmes("hello")
>>> proc({'hello': 'scrapy'})
'scrapy'
>>> proc({'hello': {'scrapy': 'world'}})
{'scrapy': 'world'}
以下是匯入 json 查詢值的程式碼:
>>> import json
>>> proc_single_json_str = Compose(json.loads, SelectJmes("hello"))
>>> proc_single_json_str('{"hello": "scrapy"}')
u'scrapy'
>>> proc_json_list = Compose(json.loads, MapCompose(SelectJmes('hello')))
>>> proc_json_list('[{"hello":"scrapy"}, {"world":"env"}]')
[u'scrapy']
Scrapy - Shell
描述
Scrapy shell 可用於抓取無錯誤程式碼的資料,無需使用爬蟲。Scrapy shell 的主要目的是測試提取的程式碼、XPath 或 CSS 表示式。它還有助於指定您從中抓取資料的網頁。
配置 Shell
Shell 可以透過安裝IPython(用於互動式計算)控制檯來配置,它是一個功能強大的互動式 Shell,提供自動完成、彩色輸出等功能。
如果您在 Unix 平臺上工作,則最好安裝 IPython。如果無法訪問 IPython,您也可以使用bpython。
您可以透過設定名為 SCRAPY_PYTHON_SHELL 的環境變數或透過如下定義 scrapy.cfg 檔案來配置 Shell:
[settings] shell = bpython
啟動 Shell
可以使用以下命令啟動 Scrapy shell:
scrapy shell <url>
url指定需要抓取資料 的URL。
使用 Shell
Shell 提供了一些額外的快捷方式和 Scrapy 物件,如下表所述:
可用的快捷方式
Shell 在專案中提供以下可用的快捷方式:
| 序號 | 快捷方式及描述 |
|---|---|
| 1 | shelp() 它使用幫助選項提供可用的物件和快捷方式。 |
| 2 | fetch(request_or_url) 它從請求或 URL 中收集響應,並且相關物件將正確更新。 |
| 3 | view(response) 您可以在本地瀏覽器中檢視給定請求的響應,以便觀察並正確顯示外部連結,它會將 base 標籤附加到響應主體。 |
可用的 Scrapy 物件
Shell 在專案中提供以下可用的 Scrapy 物件:
| 序號 | 物件及描述 |
|---|---|
| 1 | 爬蟲 它指定當前的爬蟲物件。 |
| 2 | spider 如果沒有當前 URL 的爬蟲,則它將透過定義新的爬蟲來處理 URL 或爬蟲物件。 |
| 3 | request 它指定最後一個收集頁面的請求物件。 |
| 4 | response 它指定了最後一個收集到的頁面的響應物件。 |
| 5 | 設定 它提供當前的 Scrapy 設定。 |
Shell 會話示例
讓我們嘗試抓取 scrapy.org 網站,然後按照描述開始從 reddit.com 抓取資料。
在繼續之前,首先我們將啟動 shell,如下面的命令所示:
scrapy shell 'http://scrapy.org' --nolog
使用以上 URL 時,Scrapy 將顯示可用的物件:
[s] Available Scrapy objects:
[s] crawler <scrapy.crawler.Crawler object at 0x1e16b50>
[s] item {}
[s] request <GET http://scrapy.org >
[s] response <200 http://scrapy.org >
[s] settings <scrapy.settings.Settings object at 0x2bfd650>
[s] spider <Spider 'default' at 0x20c6f50>
[s] Useful shortcuts:
[s] shelp() Provides available objects and shortcuts with help option
[s] fetch(req_or_url) Collects the response from the request or URL and associated
objects will get update
[s] view(response) View the response for the given request
接下來,開始使用物件的運作,如下所示:
>> response.xpath('//title/text()').extract_first()
u'Scrapy | A Fast and Powerful Scraping and Web Crawling Framework'
>> fetch("http://reddit.com")
[s] Available Scrapy objects:
[s] crawler
[s] item {}
[s] request
[s] response <200 https://www.reddit.com/>
[s] settings
[s] spider
[s] Useful shortcuts:
[s] shelp() Shell help (print this help)
[s] fetch(req_or_url) Fetch request (or URL) and update local objects
[s] view(response) View response in a browser
>> response.xpath('//title/text()').extract()
[u'reddit: the front page of the internet']
>> request = request.replace(method="POST")
>> fetch(request)
[s] Available Scrapy objects:
[s] crawler
...
從 Spider 呼叫 Shell 以檢查響應
只有在你期望獲得該響應時,才能檢查從 spider 處理的響應。
例如:
import scrapy
class SpiderDemo(scrapy.Spider):
name = "spiderdemo"
start_urls = [
"http://mysite.com",
"http://mysite1.org",
"http://mysite2.net",
]
def parse(self, response):
# You can inspect one specific response
if ".net" in response.url:
from scrapy.shell import inspect_response
inspect_response(response, self)
如上程式碼所示,您可以使用以下函式從 spider 呼叫 shell 以檢查響應:
scrapy.shell.inspect_response
現在執行 spider,您將看到以下螢幕:
2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None) 2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None) 2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None) [s] Available Scrapy objects: [s] crawler ... >> response.url 'http://mysite2.org'
您可以使用以下程式碼檢查提取的程式碼是否有效:
>> response.xpath('//div[@class = "val"]')
它顯示輸出為
[]
以上行僅顯示空白輸出。現在您可以呼叫 shell 檢查響應,如下所示:
>> view(response)
它顯示響應為
True
Scrapy - 專案管道
描述
Item Pipeline 是一種處理抓取專案的的方法。當一個專案傳送到 Item Pipeline 時,它會被 spider 抓取並使用多個元件進行處理,這些元件按順序執行。
每當收到一個專案時,它都會決定以下兩種操作之一:
- 繼續處理專案。
- 從管道中刪除它。
- 停止處理專案。
Item Pipeline 通常用於以下目的:
- 將抓取的專案儲存在資料庫中。
- 如果收到的專案重複,則它將刪除重複的專案。
- 它將檢查專案是否包含目標欄位。
- 清除 HTML 資料。
語法
您可以使用以下方法編寫 Item Pipeline:
process_item(self, item, spider)
以上方法包含以下引數:
- Item(item 物件或字典) - 它指定抓取的專案。
- spider(spider 物件) - 抓取專案的 spider。
您可以使用下表中提供的其他方法:
| 序號 | 方法及描述 | 引數 |
|---|---|---|
| 1 | open_spider(self, spider) 當 spider 開啟時選擇它。 |
spider(spider 物件) - 它指的是已開啟的 spider。 |
| 2 | close_spider(self, spider) 當 spider 關閉時選擇它。 |
spider(spider 物件) - 它指的是已關閉的 spider。 |
| 3 | from_crawler(cls, crawler) 藉助 crawler,pipeline 可以訪問 Scrapy 的核心元件,例如訊號和設定。 |
crawler(Crawler 物件) - 它指的是使用此 pipeline 的 crawler。 |
示例
以下是不同概念中使用的 item pipeline 示例。
刪除沒有標籤的專案
在以下程式碼中,pipeline 為那些不包含增值稅(excludes_vat 屬性)的專案平衡(price)屬性,並忽略那些沒有價格標籤的專案:
from Scrapy.exceptions import DropItem
class PricePipeline(object):
vat = 2.25
def process_item(self, item, spider):
if item['price']:
if item['excludes_vat']:
item['price'] = item['price'] * self.vat
return item
else:
raise DropItem("Missing price in %s" % item)
將專案寫入 JSON 檔案
以下程式碼將從所有 spider 抓取的所有專案儲存到單個items.jl檔案中,該檔案包含每行一個專案,以 JSON 格式的序列化形式儲存。JsonWriterPipeline 類用於在程式碼中演示如何編寫 item pipeline:
import json
class JsonWriterPipeline(object):
def __init__(self):
self.file = open('items.jl', 'wb')
def process_item(self, item, spider):
line = json.dumps(dict(item)) + "\n"
self.file.write(line)
return item
將專案寫入 MongoDB
您可以在 Scrapy 設定中指定 MongoDB 地址和資料庫名稱,並且 MongoDB 集合可以以 item 類命名。以下程式碼描述瞭如何使用from_crawler()方法正確收集資源:
import pymongo
class MongoPipeline(object):
collection_name = 'Scrapy_list'
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
@classmethod
def from_crawler(cls, crawler):
return cls(
mongo_uri = crawler.settings.get('MONGO_URI'),
mongo_db = crawler.settings.get('MONGO_DB', 'lists')
)
def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def close_spider(self, spider):
self.client.close()
def process_item(self, item, spider):
self.db[self.collection_name].insert(dict(item))
return item
重複過濾器
過濾器將檢查重複的專案,並刪除已處理的專案。在以下程式碼中,我們為專案使用了唯一的 ID,但 spider 返回了許多具有相同 ID 的專案:
from scrapy.exceptions import DropItem
class DuplicatesPipeline(object):
def __init__(self):
self.ids_seen = set()
def process_item(self, item, spider):
if item['id'] in self.ids_seen:
raise DropItem("Repeated items found: %s" % item)
else:
self.ids_seen.add(item['id'])
return item
啟用 Item Pipeline
您可以透過將 Item Pipeline 元件的類新增到ITEM_PIPELINES設定中來啟用它,如下面的程式碼所示。您可以按照它們執行的順序為類分配整數值(順序可以是從較低值到較高值的類),並且值將在 0-1000 範圍內。
ITEM_PIPELINES = {
'myproject.pipelines.PricePipeline': 100,
'myproject.pipelines.JsonWriterPipeline': 600,
}
Scrapy - 資料匯出
描述
Feed 匯出是儲存從站點抓取的資料的一種方法,即生成一個“匯出檔案”。
序列化格式
Feed 匯出使用 Item 匯出器,並使用多種序列化格式和儲存後端生成包含抓取專案的 Feed。
下表顯示了支援的格式:
| 序號 | 格式和描述 |
|---|---|
| 1 | JSON FEED_FORMAT 為json 使用的匯出器為class scrapy.exporters.JsonItemExporter |
| 2 | JSON 行 FEED_FROMAT 為jsonlines 使用的匯出器為class scrapy.exporters.JsonLinesItemExporter |
| 3 | CSV FEED_FORMAT 為CSV 使用的匯出器為class scrapy.exporters.CsvItemExporter |
| 4 | XML FEED_FORMAT 為xml 使用的匯出器為class scrapy.exporters.XmlItemExporter |
使用FEED_EXPORTERS設定,還可以擴充套件支援的格式:
| 序號 | 格式和描述 |
|---|---|
| 1 | Pickle FEED_FORMAT 為 pickel 使用的匯出器為class scrapy.exporters.PickleItemExporter |
| 2 | Marshal FEED_FORMAT 為 marshal 使用的匯出器為class scrapy.exporters.MarshalItemExporter |
儲存後端
儲存後端定義了使用 URI 將 Feed 儲存在何處。
下表顯示了支援的儲存後端:
| 序號 | 儲存後端和描述 |
|---|---|
| 1 | 本地檔案系統 URI 方案為file,用於儲存 Feed。 |
| 2 | FTP URI 方案為ftp,用於儲存 Feed。 |
| 3 | S3 |
| 4 | 標準輸出 URI 方案為stdout,Feed 儲存到標準輸出。 |
儲存 URI 引數
以下是儲存 URL 的引數,在建立 Feed 時會被替換:
- %(time)s:此引數將被時間戳替換。
- %(name)s:此引數將被 spider 名稱替換。
設定
下表顯示了可用於配置 Feed 匯出的設定:
| 序號 | 設定和描述 |
|---|---|
| 1 | FEED_URI 它是匯出 Feed 的 URI,用於啟用 Feed 匯出。 |
| 2 | FEED_FORMAT 它是 Feed 使用的序列化格式。 |
| 3 | FEED_EXPORT_FIELDS 它用於定義需要匯出的欄位。 |
| 4 | FEED_STORE_EMPTY 它定義是否匯出沒有專案的 Feed。 |
| 5 | FEED_STORAGES 它是一個包含其他 Feed 儲存後端的字典。 |
| 6 | FEED_STORAGES_BASE 它是一個包含內建 Feed 儲存後端的字典。 |
| 7 | FEED_EXPORTERS 它是一個包含其他 Feed 匯出器的字典。 |
| 8 | FEED_EXPORTERS_BASE 它是一個包含內建 Feed 匯出器的字典。 |
Scrapy - 請求和響應
描述
Scrapy 可以使用Request和Response物件來抓取網站。請求物件透過系統傳遞,使用 spider 執行請求並在返回響應物件時返回請求。
請求物件
請求物件是一個生成響應的 HTTP 請求。它具有以下類:
class scrapy.http.Request(url[, callback, method = 'GET', headers, body, cookies, meta, encoding = 'utf-8', priority = 0, dont_filter = False, errback])
下表顯示了請求物件的引數:
| 序號 | 引數及描述 |
|---|---|
| 1 | url 它是一個指定 URL 請求的字串。 |
| 2 | callback 它是一個可呼叫的函式,它使用請求的響應作為第一個引數。 |
| 3 | method 它是一個指定 HTTP 方法請求的字串。 |
| 4 | headers 它是一個包含請求頭的字典。 |
| 5 | body 它是一個包含請求正文的字串或 unicode。 |
| 6 | cookies 它是一個包含請求 cookie 的列表。 |
| 7 | meta 它是一個包含請求元資料值的字典。 |
| 8 | encoding 它是一個包含用於對 URL 進行編碼的 utf-8 編碼的字串。 |
| 9 | priority 它是一個整數,排程程式使用它來定義處理請求的順序。 |
| 10 | dont_filter 它是一個布林值,指定排程程式是否不應過濾請求。 |
| 11 | errback 它是一個可呼叫的函式,當處理請求時引發異常時呼叫它。 |
將附加資料傳遞給回撥函式
下載響應後,請求的回撥函式將其作為第一個引數呼叫。
例如:
def parse_page1(self, response):
return scrapy.Request("http://www.something.com/some_page.html",
callback = self.parse_page2)
def parse_page2(self, response):
self.logger.info("%s page visited", response.url)
如果要將引數傳遞給可呼叫函式並在第二個回撥中接收這些引數,可以使用Request.meta屬性,如下面的示例所示:
def parse_page1(self, response):
item = DemoItem()
item['foremost_link'] = response.url
request = scrapy.Request("http://www.something.com/some_page.html",
callback = self.parse_page2)
request.meta['item'] = item
return request
def parse_page2(self, response):
item = response.meta['item']
item['other_link'] = response.url
return item
使用 errback 捕獲請求處理中的異常
errback 是一個可呼叫的函式,當處理請求時引發異常時呼叫它。
以下示例演示了這一點:
import scrapy
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError
from twisted.internet.error import TimeoutError, TCPTimedOutError
class DemoSpider(scrapy.Spider):
name = "demo"
start_urls = [
"http://www.httpbin.org/", # HTTP 200 expected
"http://www.httpbin.org/status/404", # Webpage not found
"http://www.httpbin.org/status/500", # Internal server error
"http://www.httpbin.org:12345/", # timeout expected
"http://www.httphttpbinbin.org/", # DNS error expected
]
def start_requests(self):
for u in self.start_urls:
yield scrapy.Request(u, callback = self.parse_httpbin,
errback = self.errback_httpbin,
dont_filter=True)
def parse_httpbin(self, response):
self.logger.info('Recieved response from {}'.format(response.url))
# ...
def errback_httpbin(self, failure):
# logs failures
self.logger.error(repr(failure))
if failure.check(HttpError):
response = failure.value.response
self.logger.error("HttpError occurred on %s", response.url)
elif failure.check(DNSLookupError):
request = failure.request
self.logger.error("DNSLookupError occurred on %s", request.url)
elif failure.check(TimeoutError, TCPTimedOutError):
request = failure.request
self.logger.error("TimeoutError occurred on %s", request.url)
Request.meta 特殊鍵
request.meta 特殊鍵是 Scrapy 識別的特殊 meta 鍵列表。
下表顯示了 Request.meta 的一些鍵:
| 序號 | 鍵和描述 |
|---|---|
| 1 | dont_redirect 當設定為 true 時,它是一個鍵,不會根據響應的狀態重定向請求。 |
| 2 | dont_retry 當設定為 true 時,它是一個鍵,不會重試失敗的請求,並且將被中介軟體忽略。 |
| 3 | handle_httpstatus_list 它是一個鍵,定義了每個請求的基礎上可以允許哪些響應程式碼。 |
| 4 | handle_httpstatus_all 它是一個鍵,用於透過將其設定為true來允許請求的任何響應程式碼。 |
| 5 | dont_merge_cookies 它是一個鍵,用於透過將其設定為true來避免與現有 cookie 合併。 |
| 6 | cookiejar 它是一個鍵,用於為每個 spider 保留多個 cookie 會話。 |
| 7 | dont_cache 它是一個鍵,用於避免在每個策略上快取 HTTP 請求和響應。 |
| 8 | redirect_urls 它是一個鍵,包含請求透過的 URL。 |
| 9 | bindaddress 它是可以用於執行請求的傳出 IP 地址的 IP。 |
| 10 | dont_obey_robotstxt 如果設定為 True,則即使啟用了 ROBOTSTXT_OBEY,也不會過濾 robots.txt 排除標準禁止的請求。 |
| 11 | 下載超時時間 用於設定每個蜘蛛的超時時間(以秒為單位),下載器將在超時前等待該時間。 |
| 12 | 下載最大大小 用於設定每個蜘蛛的下載器將下載的最大大小(以位元組為單位)。 |
| 13 | 代理 可以為 Request 物件設定代理,以便在請求中使用 HTTP 代理。 |
請求子類
可以透過繼承請求類來實現自定義功能。內建的請求子類如下:
FormRequest 物件
FormRequest 類透過擴充套件基本請求來處理 HTML 表單。它具有以下類:
class scrapy.http.FormRequest(url[,formdata, callback, method = 'GET', headers, body, cookies, meta, encoding = 'utf-8', priority = 0, dont_filter = False, errback])
以下是引數:
formdata - 它是一個包含 HTML 表單資料的字典,該字典分配給請求的主體。
注意 - 其餘引數與請求類相同,並在請求物件部分進行了說明。
除了請求方法外,FormRequest 物件還支援以下類方法:
classmethod from_response(response[, formname = None, formnumber = 0, formdata = None, formxpath = None, formcss = None, clickdata = None, dont_click = False, ...])
下表顯示了上述類的引數:
| 序號 | 引數及描述 |
|---|---|
| 1 | response 它是一個用於使用響應的 HTML 表單預填充表單欄位的物件。 |
| 2 | formname 如果指定,它是一個字串,其中包含具有 name 屬性的表單。 |
| 3 | formnumber 當響應中有多個表單時,它是要使用的表單的整數。 |
| 4 | formdata 它是表單資料中用於覆蓋的欄位的字典。 |
| 5 | formxpath 如果指定,它是一個字串,匹配 xpath 的表單將被使用。 |
| 6 | formcss 如果指定,它是一個字串,匹配 css 選擇器的表單將被使用。 |
| 7 | clickdata 它是用於觀察被點選控制元件的屬性字典。 |
| 8 | dont_click 如果設定為 True,則表單中的資料將在不點選任何元素的情況下提交。 |
示例
以下是請求使用的一些示例:
使用 FormRequest 透過 HTTP POST 傳送資料
以下程式碼演示了當您希望在蜘蛛中複製 HTML 表單 POST 時如何返回FormRequest 物件:
return [FormRequest(url = "http://www.something.com/post/action",
formdata = {'firstname': 'John', 'lastname': 'dave'},
callback = self.after_post)]
使用 FormRequest.from_response() 模擬使用者登入
通常,網站使用元素來提供預填充的表單欄位。
當您希望在抓取時自動填充這些欄位時,可以使用FormRequest.form_response() 方法。
以下示例演示了這一點。
import scrapy
class DemoSpider(scrapy.Spider):
name = 'demo'
start_urls = ['http://www.something.com/users/login.php']
def parse(self, response):
return scrapy.FormRequest.from_response(
response,
formdata = {'username': 'admin', 'password': 'confidential'},
callback = self.after_login
)
def after_login(self, response):
if "authentication failed" in response.body:
self.logger.error("Login failed")
return
# You can continue scraping here
響應物件
它是一個指示 HTTP 響應的物件,該響應被饋送到蜘蛛以進行處理。它具有以下類:
class scrapy.http.Response(url[, status = 200, headers, body, flags])
下表顯示了 Response 物件的引數:
| 序號 | 引數及描述 |
|---|---|
| 1 | url 它是一個指定 URL 響應的字串。 |
| 2 | 狀態 它是一個包含 HTTP 狀態響應的整數。 |
| 3 | headers 它是一個包含響應頭的字典。 |
| 4 | body 它是一個包含響應體的字串。 |
| 5 | 標誌 它是一個包含響應標誌的列表。 |
響應子類
可以透過繼承響應類來實現自定義功能。內建的響應子類如下:
TextResponse 物件
TextResponse 物件用於二進位制資料(如影像、聲音等),它能夠編碼基本 Response 類。它具有以下類:
class scrapy.http.TextResponse(url[, encoding[,status = 200, headers, body, flags]])
以下是引數:
encoding - 它是一個包含用於編碼響應的編碼的字串。
注意 - 其餘引數與響應類相同,並在響應物件部分進行了說明。
下表顯示了 TextResponse 物件除了響應方法外還支援的屬性:
| 序號 | 屬性 & 描述 |
|---|---|
| 1 | 文字 它是響應主體,其中可以多次訪問 response.text。 |
| 2 | encoding 它是一個包含響應編碼的字串。 |
| 3 | selector 它是在第一次訪問時例項化的屬性,並使用響應作為目標。 |
下表顯示了除了response 方法外,TextResponse 物件還支援的方法:
| 序號 | 方法及描述 |
|---|---|
| 1 | xpath (查詢) 它是 TextResponse.selector.xpath(query) 的快捷方式。 |
| 2 | css (查詢) 它是 TextResponse.selector.css(query) 的快捷方式。 |
| 3 | body_as_unicode() 它是一個作為方法提供的響應主體,其中可以多次訪問 response.text。 |
HtmlResponse 物件
它是一個支援編碼和自動發現的物件,方法是檢視 HTML 的meta httpequiv 屬性。它的引數與響應類相同,並在響應物件部分進行了說明。它具有以下類:
class scrapy.http.HtmlResponse(url[,status = 200, headers, body, flags])
XmlResponse 物件
它是一個支援編碼和自動發現的物件,方法是檢視 XML 行。它的引數與響應類相同,並在響應物件部分進行了說明。它具有以下類:
class scrapy.http.XmlResponse(url[, status = 200, headers, body, flags])
Scrapy - 連結提取器
描述
顧名思義,連結提取器是用於使用scrapy.http.Response 物件從網頁中提取連結的物件。在 Scrapy 中,有內建的提取器,例如scrapy.linkextractors 匯入LinkExtractor。您可以根據需要透過實現簡單的介面來自定義自己的連結提取器。
每個連結提取器都有一個名為extract_links 的公共方法,該方法包含一個 Response 物件並返回一個 scrapy.link.Link 物件列表。您可以只例項化一次連結提取器,並多次呼叫 extract_links 方法來提取具有不同響應的連結。CrawlSpider 類使用連結提取器和一組規則,其主要目的是提取連結。
內建連結提取器的參考
通常,連結提取器與 Scrapy 分組,並在 scrapy.linkextractors 模組中提供。預設情況下,連結提取器將是 LinkExtractor,其功能等同於 LxmlLinkExtractor:
from scrapy.linkextractors import LinkExtractor
LxmlLinkExtractor
class scrapy.linkextractors.lxmlhtml.LxmlLinkExtractor(allow = (), deny = (),
allow_domains = (), deny_domains = (), deny_extensions = None, restrict_xpaths = (),
restrict_css = (), tags = ('a', 'area'), attrs = ('href', ),
canonicalize = True, unique = True, process_value = None)
LxmlLinkExtractor 是一個強烈推薦的連結提取器,因為它具有方便的過濾選項,並且與 lxml 的強大 HTMLParser 一起使用。
| 序號 | 引數及描述 |
|---|---|
| 1 | allow(正則表示式(或列表)) 它允許一個表示式或一組表示式,這些表示式應與要提取的 url 匹配。如果未提及,它將匹配所有連結。 |
| 2 | deny(正則表示式(或列表)) 它阻止或排除一個表示式或一組表示式,這些表示式應與不應提取的 url 匹配。如果未提及或留空,則不會消除不需要的連結。 |
| 3 | allow_domains(str 或列表) 它允許一個字串或字串列表,這些字串應與要從中提取連結的域匹配。 |
| 4 | deny_domains(str 或列表) 它阻止或排除一個字串或字串列表,這些字串應與不應從中提取連結的域匹配。 |
| 5 | deny_extensions(列表) 在提取連結時,它會阻止帶有副檔名的字串列表。如果未設定,則預設情況下它將設定為IGNORED_EXTENSIONS,其中包含scrapy.linkextractors 包中預定義的列表。 |
| 6 | restrict_xpaths(str 或列表) 它是要從響應中提取連結的 XPath 列表區域。如果給出,則僅從透過 XPath 選擇的文字中提取連結。 |
| 7 | restrict_css(str 或列表) 它的行為類似於 restrict_xpaths 引數,它將從響應內部 CSS 選擇的區域提取連結。 |
| 8 | tags(str 或列表) 提取連結時應考慮的單個標籤或標籤列表。預設情況下,它將為('a','area')。 |
| 9 | attrs(列表) 提取連結時應考慮的單個屬性或屬性列表。預設情況下,它將為('href',)。 |
| 10 | canonicalize(布林值) 使用scrapy.utils.url.canonicalize_url 將提取的 url 轉換為標準形式。預設情況下,它將為 True。 |
| 11 | unique(布林值) 如果提取的連結重複,則將使用它。 |
| 12 | process_value(可呼叫物件) 它是一個函式,接收來自掃描的標籤和屬性的值。接收到的值可能會被更改和返回,或者不返回任何內容以拒絕連結。如果未使用,則預設情況下它將為 lambda x: x。 |
示例
以下程式碼用於提取連結:
<a href = "javascript:goToPage('../other/page.html'); return false">Link text</a>
以下程式碼函式可在 process_value 中使用:
def process_value(val):
m = re.search("javascript:goToPage\('(.*?)'", val)
if m:
return m.group(1)
Scrapy - 設定
描述
可以使用 Scrapy 設定修改 Scrapy 元件的行為。設定還可以選擇當前活動的 Scrapy 專案,以防您有多個 Scrapy 專案。
指定設定
在抓取網站時,必須通知 Scrapy 您正在使用哪個設定。為此,應使用環境變數SCRAPY_SETTINGS_MODULE,其值應為 Python 路徑語法。
填充設定
下表顯示了一些可以填充設定的機制:
| 序號 | 機制和描述 |
|---|---|
| 1 | 命令列選項 在此,傳遞的引數優先順序最高,覆蓋其他選項。-s 用於覆蓋一個或多個設定。 scrapy crawl myspider -s LOG_FILE = scrapy.log |
| 2 | 每個蜘蛛的設定 蜘蛛可以擁有自己的設定,透過使用屬性 custom_settings 覆蓋專案設定。 class DemoSpider(scrapy.Spider):
name = 'demo'
custom_settings = {
'SOME_SETTING': 'some value',
}
|
| 3 | 專案設定模組 在這裡,您可以填充自定義設定,例如在 settings.py 檔案中新增或修改設定。 |
| 4 | 每個命令的預設設定 每個 Scrapy 工具命令都在 default_settings 屬性中定義了自己的設定,以覆蓋全域性預設設定。 |
| 5 | 預設全域性設定 這些設定位於 scrapy.settings.default_settings 模組中。 |
訪問設定
它們可以透過 self.settings 獲取,並在蜘蛛初始化後在基本蜘蛛中設定。
以下示例演示了這一點。
class DemoSpider(scrapy.Spider):
name = 'demo'
start_urls = ['http://example.com']
def parse(self, response):
print("Existing settings: %s" % self.settings.attributes.keys())
要在初始化蜘蛛之前使用設定,必須在蜘蛛的_init_() 方法中覆蓋from_crawler 方法。您可以透過傳遞給from_crawler 方法的屬性scrapy.crawler.Crawler.settings 訪問設定。
以下示例演示了這一點。
class MyExtension(object):
def __init__(self, log_is_enabled = False):
if log_is_enabled:
print("Enabled log")
@classmethod
def from_crawler(cls, crawler):
settings = crawler.settings
return cls(settings.getbool('LOG_ENABLED'))
設定名稱的原理
設定名稱作為字首新增到它們配置的元件中。例如,對於 robots.txt 擴充套件,設定名稱可以是 ROBOTSTXT_ENABLED、ROBOTSTXT_OBEY、ROBOTSTXT_CACHEDIR 等。
內建設定參考
下表顯示了 Scrapy 的內建設定:
| 序號 | 設定和描述 |
|---|---|
| 1 | AWS_ACCESS_KEY_ID 它用於訪問 Amazon Web Services。 預設值:None |
| 2 | AWS_SECRET_ACCESS_KEY 它用於訪問 Amazon Web Services。 預設值:None |
| 3 | BOT_NAME 它是機器人的名稱,可用於構建 User-Agent。 預設值:'scrapybot' |
| 4 | CONCURRENT_ITEMS 專案處理器中存在的最大專案數,用於並行處理。 預設值:100 |
| 5 | CONCURRENT_REQUESTS Scrapy 下載器執行的現有請求的最大數量。 預設值:16 |
| 6 | CONCURRENT_REQUESTS_PER_DOMAIN 為任何單個域同時執行的現有請求的最大數量。 預設值:8 |
| 7 | CONCURRENT_REQUESTS_PER_IP 為任何單個 IP 同時執行的現有請求的最大數量。 預設值:0 |
| 8 | DEFAULT_ITEM_CLASS 它是用於表示專案的類。 預設值:'scrapy.item.Item' |
| 9 | DEFAULT_REQUEST_HEADERS 它是 Scrapy HTTP 請求使用的預設標頭。 預設值: {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,
*/*;q=0.8', 'Accept-Language': 'en',
}
|
| 10 | DEPTH_LIMIT 蜘蛛爬取任何站點的最大深度。 預設值:0 |
| 11 | DEPTH_PRIORITY 它是一個整數,用於根據深度更改請求的優先順序。 預設值:0 |
| 12 | DEPTH_STATS 它說明是否收集深度統計資訊。 預設值:True |
| 13 | DEPTH_STATS_VERBOSE 啟用此設定後,每個詳細深度級別上的請求數量都會在統計資訊中收集。 預設值:False |
| 14 | DNSCACHE_ENABLED 用於啟用記憶體中的 DNS 快取。 預設值:True |
| 15 | DNSCACHE_SIZE 定義記憶體中 DNS 快取的大小。 預設值:10000 |
| 16 | DNS_TIMEOUT 用於設定 DNS 處理查詢的超時時間。 預設值:60 |
| 17 | DOWNLOADER 用於爬取過程的下載器。 預設值:'scrapy.core.downloader.Downloader' |
| 18 | DOWNLOADER_MIDDLEWARES 一個字典,包含下載中介軟體及其順序。 預設值:{} |
| 19 | DOWNLOADER_MIDDLEWARES_BASE 一個字典,包含預設啟用的下載中介軟體。 預設值: { 'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware': 100, }
|
| 20 | DOWNLOADER_STATS 此設定用於啟用下載器統計資訊。 預設值:True |
| 21 | DOWNLOAD_DELAY 定義下載器在從站點下載頁面之前等待的總時間。 預設值:0 |
| 22 | DOWNLOAD_HANDLERS 一個包含下載處理程式的字典。 預設值:{} |
| 23 | DOWNLOAD_HANDLERS_BASE 一個包含預設啟用的下載處理程式的字典。 預設值: { 'file': 'scrapy.core.downloader.handlers.file.FileDownloadHandler', }
|
| 24 | DOWNLOAD_TIMEOUT 下載器在超時之前等待的總時間。 預設值:180 |
| 25 | DOWNLOAD_MAXSIZE 下載器允許下載的響應的最大大小。 預設值:1073741824 (1024MB) |
| 26 | DOWNLOAD_WARNSIZE 定義下載器發出警告的響應大小。 預設值:33554432 (32MB) |
| 27 | DUPEFILTER_CLASS 用於檢測和過濾重複請求的類。 預設值:'scrapy.dupefilters.RFPDupeFilter' |
| 28 | DUPEFILTER_DEBUG 設定為 true 時,此設定會記錄所有重複過濾器。 預設值:False |
| 29 | EDITOR 使用 edit 命令編輯蜘蛛時使用。 預設值:取決於環境 |
| 30 | EXTENSIONS 一個字典,包含在專案中啟用的擴充套件。 預設值:{} |
| 31 | EXTENSIONS_BASE 一個字典,包含內建擴充套件。 預設值:{ 'scrapy.extensions.corestats.CoreStats': 0, } |
| 32 | FEED_TEMPDIR 用於設定自定義資料夾,爬蟲臨時檔案可以儲存在此資料夾中。 |
| 33 | ITEM_PIPELINES 一個包含管道(pipelines)的字典。 預設值:{} |
| 34 | LOG_ENABLED 定義是否啟用日誌記錄。 預設值:True |
| 35 | LOG_ENCODING 定義用於日誌記錄的編碼型別。 預設值:'utf-8' |
| 36 | LOG_FILE 用於日誌記錄輸出的檔名。 預設值:None |
| 37 | LOG_FORMAT 一個字串,用於格式化日誌訊息。 預設值:'%(asctime)s [%(name)s] %(levelname)s: %(message)s' |
| 38 | LOG_DATEFORMAT 一個字串,用於格式化日期/時間。 預設值:'%Y-%m-%d %H:%M:%S' |
| 39 | LOG_LEVEL 定義最低日誌級別。 預設值:'DEBUG' |
| 40 | LOG_STDOUT 如果此設定設定為 true,則所有程序輸出都將顯示在日誌中。 預設值:False |
| 41 | MEMDEBUG_ENABLED 定義是否啟用記憶體除錯。 預設值:False |
| 42 | MEMDEBUG_NOTIFY 定義啟用記憶體除錯時傳送到特定地址的記憶體報告。 預設值:[] |
| 43 | MEMUSAGE_ENABLED 定義當 Scrapy 程序超過記憶體限制時是否啟用記憶體使用情況監控。 預設值:False |
| 44 | MEMUSAGE_LIMIT_MB 定義允許的最大記憶體限制(以兆位元組為單位)。 預設值:0 |
| 45 | MEMUSAGE_CHECK_INTERVAL_SECONDS 透過設定間隔長度來檢查當前記憶體使用情況。 預設值:60.0 |
| 46 | MEMUSAGE_NOTIFY_MAIL 當記憶體達到限制時,使用一組電子郵件進行通知。 預設值:False |
| 47 | MEMUSAGE_REPORT 定義在關閉每個蜘蛛時是否傳送記憶體使用情況報告。 預設值:False |
| 48 | MEMUSAGE_WARNING_MB 定義在傳送警告之前允許的總記憶體。 預設值:0 |
| 49 | NEWSPIDER_MODULE 使用 genspider 命令建立新蜘蛛時使用的模組。 預設值:'' |
| 50 | RANDOMIZE_DOWNLOAD_DELAY 定義 Scrapy 在從站點下載請求時等待的隨機時間量。 預設值:True |
| 51 | REACTOR_THREADPOOL_MAXSIZE 定義反應器執行緒池的最大大小。 預設值:10 |
| 52 | REDIRECT_MAX_TIMES 定義請求可以重定向的次數。 預設值:20 |
| 53 | REDIRECT_PRIORITY_ADJUST 啟用此設定後,會調整請求的重定向優先順序。 預設值:+2 |
| 54 | RETRY_PRIORITY_ADJUST 啟用此設定後,會調整請求的重試優先順序。 預設值:-1 |
| 55 | ROBOTSTXT_OBEY 設定為 true 時,Scrapy 會遵守 robots.txt 策略。 預設值:False |
| 56 | SCHEDULER 定義用於爬取的排程器。 預設值:'scrapy.core.scheduler.Scheduler' |
| 57 | SPIDER_CONTRACTS 專案中用於測試蜘蛛的蜘蛛契約的字典。 預設值:{} |
| 58 | SPIDER_CONTRACTS_BASE 一個字典,包含 Scrapy 預設啟用的契約。 預設值: {
'scrapy.contracts.default.UrlContract' : 1,
'scrapy.contracts.default.ReturnsContract': 2,
}
|
| 59 | SPIDER_LOADER_CLASS 定義一個類,該類實現 SpiderLoader API 來載入蜘蛛。 預設值:'scrapy.spiderloader.SpiderLoader' |
| 60 | SPIDER_MIDDLEWARES 一個字典,包含蜘蛛中介軟體。 預設值:{} |
| 61 | SPIDER_MIDDLEWARES_BASE 一個字典,包含 Scrapy 預設啟用的蜘蛛中介軟體。 預設值: {
'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': 50,
}
|
| 62 | SPIDER_MODULES 一個包含蜘蛛的模組列表,Scrapy 將在其中查詢蜘蛛。 預設值:[] |
| 63 | STATS_CLASS 一個類,該類實現 Stats Collector API 來收集統計資訊。 預設值:'scrapy.statscollectors.MemoryStatsCollector' |
| 64 | STATS_DUMP 設定為 true 時,此設定會將統計資訊轉儲到日誌中。 預設值:True |
| 65 | STATSMAILER_RCPTS 蜘蛛完成抓取後,Scrapy 使用此設定傳送統計資訊。 預設值:[] |
| 66 | TELNETCONSOLE_ENABLED 定義是否啟用 telnetconsole。 預設值:True |
| 67 | TELNETCONSOLE_PORT 定義 telnet 控制檯的埠。 預設值:[6023, 6073] |
| 68 | TEMPLATES_DIR 包含在建立新專案時可用的模板的目錄。 預設值:scrapy 模組內的 templates 目錄 |
| 69 | URLLENGTH_LIMIT 定義允許抓取的 URL 的最大長度限制。 預設值:2083 |
| 70 | USER_AGENT 定義在爬取站點時使用的使用者代理。 預設值:"Scrapy/VERSION (+http://scrapy.org)" |
有關其他 Scrapy 設定,請訪問此 連結。
Scrapy - 異常
描述
不規則事件被稱為異常。在 Scrapy 中,由於配置丟失、從專案管道中刪除專案等原因會導致異常。以下是 Scrapy 中提到的異常及其應用列表。
DropItem
專案管道利用此異常在任何階段停止處理專案。可以寫成:
exception (scrapy.exceptions.DropItem)
CloseSpider
此異常用於使用回撥請求停止蜘蛛。可以寫成:
exception (scrapy.exceptions.CloseSpider)(reason = 'cancelled')
它包含一個名為 reason (str) 的引數,用於指定關閉的原因。
例如,以下程式碼顯示了此異常的使用:
def parse_page(self, response):
if 'Bandwidth exceeded' in response.body:
raise CloseSpider('bandwidth_exceeded')
IgnoreRequest
此異常由排程器或下載中介軟體用於忽略請求。可以寫成:
exception (scrapy.exceptions.IgnoreRequest)
NotConfigured
表示配置丟失的情況,應在元件建構函式中引發。
exception (scrapy.exceptions.NotConfigured)
如果停用以下任何元件,則可以引發此異常。
- 擴充套件
- 專案管道
- 下載中介軟體
- 蜘蛛中介軟體
NotSupported
當任何功能或方法不受支援時引發此異常。可以寫成:
exception (scrapy.exceptions.NotSupported)
Scrapy - 建立專案
描述
要從網頁中抓取資料,首先需要建立 Scrapy 專案,用於儲存程式碼。要建立新目錄,請執行以下命令:
scrapy startproject first_scrapy
以上程式碼將建立一個名為 first_scrapy 的目錄,它將包含以下結構:
first_scrapy/ scrapy.cfg # deploy configuration file first_scrapy/ # project's Python module, you'll import your code from here __init__.py items.py # project items file pipelines.py # project pipelines file settings.py # project settings file spiders/ # a directory where you'll later put your spiders __init__.py
Scrapy - 定義專案
描述
專案是用於收集從網站抓取的資料的容器。您必須透過定義專案來啟動蜘蛛。要定義專案,請編輯位於目錄 first_scrapy(自定義目錄)下的 items.py 檔案。items.py 如下所示:
import scrapy
class First_scrapyItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
MyItem 類繼承自 Item,其中包含 Scrapy 已為我們構建的許多預定義物件。例如,如果要從站點中提取名稱、URL 和描述,則需要為這三個屬性中的每一個定義欄位。
因此,讓我們新增要收集的專案:
from scrapy.item import Item, Field class First_scrapyItem(scrapy.Item): name = scrapy.Field() url = scrapy.Field() desc = scrapy.Field()
Scrapy - 第一個爬蟲
描述
蜘蛛是一個類,用於定義要從中提取資料的初始 URL、如何遵循分頁連結以及如何提取和解析在 items.py 中定義的欄位。Scrapy 提供不同型別的蜘蛛,每個蜘蛛都有特定的用途。
在 first_scrapy/spiders 目錄下建立一個名為 "first_spider.py" 的檔案,我們可以在其中告訴 Scrapy 如何找到我們正在查詢的確切資料。為此,您必須定義一些屬性:
name - 定義蜘蛛的唯一名稱。
allowed_domains - 包含蜘蛛要爬取的基本 URL。
start-urls - 蜘蛛開始爬取的 URL 列表。
parse() - 用於提取和解析抓取資料的函式。
以下程式碼演示了蜘蛛程式碼的外觀:
import scrapy
class firstSpider(scrapy.Spider):
name = "first"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
]
def parse(self, response):
filename = response.url.split("/")[-2] + '.html'
with open(filename, 'wb') as f:
f.write(response.body)
Scrapy - 爬取
描述
要執行您的蜘蛛,請在您的 first_scrapy 目錄中執行以下命令:
scrapy crawl first
其中,first 是建立蜘蛛時指定的蜘蛛名稱。
蜘蛛爬取完成後,您可以看到以下輸出:
2016-08-09 18:13:07-0400 [scrapy] INFO: Scrapy started (bot: tutorial)
2016-08-09 18:13:07-0400 [scrapy] INFO: Optional features available: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Overridden settings: {}
2016-08-09 18:13:07-0400 [scrapy] INFO: Enabled extensions: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Enabled downloader middlewares: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Enabled spider middlewares: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Enabled item pipelines: ...
2016-08-09 18:13:07-0400 [scrapy] INFO: Spider opened
2016-08-09 18:13:08-0400 [scrapy] DEBUG: Crawled (200)
<GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None)
2016-08-09 18:13:09-0400 [scrapy] DEBUG: Crawled (200)
<GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None)
2016-08-09 18:13:09-0400 [scrapy] INFO: Closing spider (finished)
如您在輸出中看到的,對於每個 URL,都有一行日誌 (referer: None) 表示這些 URL 是起始 URL,並且沒有引用方。接下來,您應該會看到在您的 first_scrapy 目錄中建立了兩個名為 Books.html 和 Resources.html 的新檔案。
Scrapy - 提取專案
描述
為了從網頁中提取資料,Scrapy 使用一種稱為選擇器的技術,該技術基於 XPath 和 CSS 表示式。以下是 XPath 表示式的一些示例:
/html/head/title - 這將選擇 HTML 文件的 <head> 元素內的 <title> 元素。
/html/head/title/text() - 這將選擇同一 <title> 元素內的文字。
//td - 這將選擇所有 <td> 元素。
//div[@class = "slice"] - 這將選擇所有包含屬性 class = "slice" 的 div 元素
選擇器有四種基本方法,如下表所示:
| 序號 | 方法及描述 |
|---|---|
| 1 | extract() 它返回一個包含所選資料的 Unicode 字串。 |
| 2 | re() 它返回一個 Unicode 字串列表,當正則表示式作為引數給出時提取。 |
| 3 | xpath() 它返回一個選擇器列表,表示由作為引數給出的 xpath 表示式選擇節點。 |
| 4 | css() 它返回一個選擇器列表,表示由作為引數給出的 CSS 表示式選擇節點。 |
在 Shell 中使用選擇器
要使用內建的 Scrapy shell 演示選擇器,您需要在系統中安裝 IPython。這裡需要注意的是,在執行 Scrapy 時,URL 應包含在引號中;否則,包含 '&' 字元的 URL 將無法工作。您可以在專案的頂級目錄中使用以下命令啟動 Shell:
scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"
Shell 如下所示:
[ ... Scrapy log here ... ]
2014-01-23 17:11:42-0400 [scrapy] DEBUG: Crawled (200)
<GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>(referer: None)
[s] Available Scrapy objects:
[s] crawler <scrapy.crawler.Crawler object at 0x3636b50>
[s] item {}
[s] request <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
[s] response <200 http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
[s] settings <scrapy.settings.Settings object at 0x3fadc50>
[s] spider <Spider 'default' at 0x3cebf50>
[s] Useful shortcuts:
[s] shelp() Shell help (print this help)
[s] fetch(req_or_url) Fetch request (or URL) and update local objects
[s] view(response) View response in a browser
In [1]:
當 Shell 載入時,您可以分別使用 response.body 和 response.header 訪問響應體或響應頭。類似地,您可以使用 response.selector.xpath() 或 response.selector.css() 對響應執行查詢。
例如:
In [1]: response.xpath('//title')
Out[1]: [<Selector xpath = '//title' data = u'<title>My Book - Scrapy'>]
In [2]: response.xpath('//title').extract()
Out[2]: [u'<title>My Book - Scrapy: Index: Chapters</title>']
In [3]: response.xpath('//title/text()')
Out[3]: [<Selector xpath = '//title/text()' data = u'My Book - Scrapy: Index:'>]
In [4]: response.xpath('//title/text()').extract()
Out[4]: [u'My Book - Scrapy: Index: Chapters']
In [5]: response.xpath('//title/text()').re('(\w+):')
Out[5]: [u'Scrapy', u'Index', u'Chapters']
提取資料
要從普通的 HTML 網站提取資料,我們必須檢查網站的原始碼以獲取 XPath。檢查後,您可以看到資料將位於ul標籤中。選擇li標籤內的元素。
以下程式碼行顯示了不同型別資料的提取 -
用於選擇 li 標籤內的資料 -
response.xpath('//ul/li')
用於選擇描述 -
response.xpath('//ul/li/text()').extract()
用於選擇網站標題 -
response.xpath('//ul/li/a/text()').extract()
用於選擇網站連結 -
response.xpath('//ul/li/a/@href').extract()
以下程式碼演示了上述提取器的用法 -
import scrapy
class MyprojectSpider(scrapy.Spider):
name = "project"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
]
def parse(self, response):
for sel in response.xpath('//ul/li'):
title = sel.xpath('a/text()').extract()
link = sel.xpath('a/@href').extract()
desc = sel.xpath('text()').extract()
print title, link, desc
Scrapy - 使用專案
描述
Item 物件是 Python 的常規字典。我們可以使用以下語法訪問類的屬性 -
>>> item = DmozItem() >>> item['title'] = 'sample title' >>> item['title'] 'sample title'
將以上程式碼新增到以下示例中 -
import scrapy
from tutorial.items import DmozItem
class MyprojectSpider(scrapy.Spider):
name = "project"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
]
def parse(self, response):
for sel in response.xpath('//ul/li'):
item = DmozItem()
item['title'] = sel.xpath('a/text()').extract()
item['link'] = sel.xpath('a/@href').extract()
item['desc'] = sel.xpath('text()').extract()
yield item
上述爬蟲的輸出將是 -
[scrapy] DEBUG: Scraped from <200
http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
{'desc': [u' - By David Mertz; Addison Wesley. Book in progress, full text,
ASCII format. Asks for feedback. [author website, Gnosis Software, Inc.\n],
'link': [u'http://gnosis.cx/TPiP/'],
'title': [u'Text Processing in Python']}
[scrapy] DEBUG: Scraped from <200
http://www.dmoz.org/Computers/Programming/Languages/Python/Books/>
{'desc': [u' - By Sean McGrath; Prentice Hall PTR, 2000, ISBN 0130211192,
has CD-ROM. Methods to build XML applications fast, Python tutorial, DOM and
SAX, new Pyxie open source XML processing library. [Prentice Hall PTR]\n'],
'link': [u'http://www.informit.com/store/product.aspx?isbn=0130211192'],
'title': [u'XML Processing with Python']}
Scrapy - 跟蹤連結
描述
在本章中,我們將學習如何提取我們感興趣的頁面連結,跟蹤它們並從該頁面提取資料。為此,我們需要在我們的之前程式碼中進行以下更改,如下所示 -
import scrapy
from tutorial.items import DmozItem
class MyprojectSpider(scrapy.Spider):
name = "project"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/",
]
def parse(self, response):
for href in response.css("ul.directory.dir-col > li > a::attr('href')"):
url = response.urljoin(href.extract())
yield scrapy.Request(url, callback = self.parse_dir_contents)
def parse_dir_contents(self, response):
for sel in response.xpath('//ul/li'):
item = DmozItem()
item['title'] = sel.xpath('a/text()').extract()
item['link'] = sel.xpath('a/@href').extract()
item['desc'] = sel.xpath('text()').extract()
yield item
以上程式碼包含以下方法 -
parse() - 它將提取我們感興趣的連結。
response.urljoin - parse() 方法將使用此方法構建一個新的 URL 並提供一個新的請求,該請求稍後將傳送到回撥。
parse_dir_contents() - 這是一個回撥,它將實際抓取感興趣的資料。
在這裡,Scrapy 使用回撥機制來跟蹤連結。使用此機制,可以設計更大的爬蟲,並可以跟蹤感興趣的連結以從不同的頁面抓取所需的資料。常規方法將是回撥方法,它將提取專案,查詢要跟蹤的下一個頁面的連結,然後為同一個回撥提供請求。
以下示例生成一個迴圈,它將跟蹤指向下一頁的連結。
def parse_articles_follow_next_page(self, response):
for article in response.xpath("//article"):
item = ArticleItem()
... extract article data here
yield item
next_page = response.css("ul.navigation > li.next-page > a::attr('href')")
if next_page:
url = response.urljoin(next_page[0].extract())
yield scrapy.Request(url, self.parse_articles_follow_next_page)
Scrapy - 爬取資料
描述
儲存抓取資料的最佳方法是使用 Feed 匯出,這確保了使用多種序列化格式正確儲存資料。JSON、JSON 行、CSV、XML 是序列化格式中現成的支援格式。可以使用以下命令儲存資料 -
scrapy crawl dmoz -o data.json
此命令將建立一個包含 JSON 格式抓取資料的data.json檔案。此技術適用於少量資料。如果需要處理大量資料,則可以使用 Item Pipeline。就像 data.json 檔案一樣,在專案建立時會在tutorial/pipelines.py中設定一個保留檔案。
Scrapy - 日誌
描述
日誌記錄意味著跟蹤事件,它使用內建的日誌記錄系統並定義函式和類來實現應用程式和庫。日誌記錄是一種現成的材料,可以與列在日誌記錄設定中的 Scrapy 設定一起使用。
Scrapy 將設定一些預設設定並在執行命令時在 scrapy.utils.log.configure_logging() 的幫助下處理這些設定。
日誌級別
在 Python 中,日誌訊息有五個不同的嚴重級別。以下列表按升序顯示標準日誌訊息 -
logging.DEBUG - 用於除錯訊息(最低嚴重性)
logging.INFO - 用於資訊訊息
logging.WARNING - 用於警告訊息
logging.ERROR - 用於常規錯誤
logging.CRITICAL - 用於嚴重錯誤(最高嚴重性)
如何記錄訊息
以下程式碼顯示了使用logging.info級別記錄訊息。
import logging
logging.info("This is an information")
以上日誌訊息可以使用logging.log作為引數傳遞,如下所示 -
import logging logging.log(logging.INFO, "This is an information")
現在,您還可以使用記錄器使用日誌記錄幫助程式日誌記錄來包含訊息,以使日誌記錄訊息清晰地顯示,如下所示 -
import logging
logger = logging.getLogger()
logger.info("This is an information")
可以有多個記錄器,可以透過使用logging.getLogger函式獲取其名稱來訪問它們,如下所示。
import logging
logger = logging.getLogger('mycustomlogger')
logger.info("This is an information")
可以使用包含模組路徑的__name__變數為任何模組使用自定義記錄器,如下所示 -
import logging
logger = logging.getLogger(__name__)
logger.info("This is an information")
從 Spider 中記錄日誌
每個 Spider 例項在其內部都有一個logger,可以使用如下 -
import scrapy
class LogSpider(scrapy.Spider):
name = 'logspider'
start_urls = ['http://dmoz.com']
def parse(self, response):
self.logger.info('Parse function called on %s', response.url)
在以上程式碼中,記錄器是使用 Spider 的名稱建立的,但您可以使用 Python 提供的任何自定義記錄器,如下面的程式碼所示 -
import logging
import scrapy
logger = logging.getLogger('customizedlogger')
class LogSpider(scrapy.Spider):
name = 'logspider'
start_urls = ['http://dmoz.com']
def parse(self, response):
logger.info('Parse function called on %s', response.url)
日誌記錄配置
記錄器無法自行顯示它們傳送的訊息。因此,它們需要“處理程式”來顯示這些訊息,並且處理程式將把這些訊息重定向到其各自的目標,例如檔案、電子郵件和標準輸出。
根據以下設定,Scrapy 將為記錄器配置處理程式。
日誌記錄設定
以下設定用於配置日誌記錄 -
LOG_FILE和LOG_ENABLED決定日誌訊息的目標。
當您將LOG_ENCODING設定為 false 時,它不會顯示日誌輸出訊息。
LOG_LEVEL將確定訊息的嚴重性順序;嚴重性較低的訊息將被過濾掉。
LOG_FORMAT和LOG_DATEFORMAT用於指定所有訊息的佈局。
當您將LOG_STDOUT設定為 true 時,程序的所有標準輸出和錯誤訊息都將重定向到日誌。
命令列選項
可以透過傳遞命令列引數來覆蓋 Scrapy 設定,如下表所示 -
| 序號 | 命令和描述 |
|---|---|
| 1 | --logfile FILE 覆蓋LOG_FILE |
| 2 | --loglevel/-L LEVEL 覆蓋LOG_LEVEL |
| 3 | --nolog 將LOG_ENABLED設定為 False |
scrapy.utils.log 模組
此函式可用於初始化 Scrapy 的日誌記錄預設值。
scrapy.utils.log.configure_logging(settings = None, install_root_handler = True)
| 序號 | 引數及描述 |
|---|---|
| 1 | settings (dict, None) 它建立並配置根記錄器的處理程式。預設情況下,它是None。 |
| 2 | install_root_handler (bool) 它指定安裝根日誌記錄處理程式。預設情況下,它是True。 |
以上函式 -
- 透過 Python 標準日誌記錄路由警告和扭曲的日誌記錄。
- 將 DEBUG 分配給 Scrapy,並將 ERROR 級別分配給 Twisted 記錄器。
- 如果 LOG_STDOUT 設定為 true,則將標準輸出路由到日誌。
可以使用settings引數覆蓋預設選項。如果未指定設定,則使用預設值。當 install_root_handler 設定為 true 時,可以為根記錄器建立處理程式。如果將其設定為 false,則不會設定任何日誌輸出。使用 Scrapy 命令時,configure_logging 將自動呼叫,並且在執行自定義指令碼時可以顯式執行。
要手動配置日誌記錄的輸出,您可以使用logging.basicConfig(),如下所示 -
import logging from scrapy.utils.log import configure_logging configure_logging(install_root_handler = False) logging.basicConfig ( filename = 'logging.txt', format = '%(levelname)s: %(your_message)s', level = logging.INFO )
Scrapy - 統計收集
描述
Stats Collector 是 Scrapy 提供的一個工具,用於以鍵/值對的形式收集統計資訊,並且可以透過 Crawler API 訪問它(Crawler 提供對所有 Scrapy 核心元件的訪問)。統計資訊收集器為每個蜘蛛提供一個統計資訊表,其中統計資訊收集器在蜘蛛開啟時自動開啟,並在蜘蛛關閉時關閉統計資訊收集器。
常見的統計資訊收集器用途
以下程式碼使用stats屬性訪問統計資訊收集器。
class ExtensionThatAccessStats(object):
def __init__(self, stats):
self.stats = stats
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.stats)
下表顯示了可用於統計資訊收集器的各種選項 -
| 序號 | 引數 | 描述 |
|---|---|---|
| 1 |
stats.set_value('hostname', socket.gethostname())
|
用於設定統計資訊值。 |
| 2 |
stats.inc_value('customized_count')
|
遞增統計資訊值。 |
| 3 |
stats.max_value('max_items_scraped', value)
|
僅當大於先前的值時,才能設定統計資訊值。 |
| 4 |
stats.min_value('min_free_memory_percent', value)
|
僅當小於先前的值時,才能設定統計資訊值。 |
| 5 |
stats.get_value('customized_count')
|
獲取統計資訊值。 |
| 6 |
stats.get_stats() {'custom_count': 1, 'start_time':
datetime.datetime(2009, 7, 14, 21, 47, 28, 977139)}
|
獲取所有統計資訊 |
可用的統計資訊收集器
Scrapy 提供不同型別的統計資訊收集器,可以透過STATS_CLASS設定訪問它們。
MemoryStatsCollector
它是預設的 Stats 收集器,它維護每個用於抓取的蜘蛛的統計資訊,並且資料將儲存在記憶體中。
class scrapy.statscollectors.MemoryStatsCollector
DummyStatsCollector
此統計資訊收集器非常高效,什麼也不做。這可以透過STATS_CLASS設定來設定,並且可以用於停用統計資訊收集以提高效能。
class scrapy.statscollectors.DummyStatsCollector
Scrapy - 傳送電子郵件
描述
Scrapy 可以使用其自己的名為Twisted 非阻塞 IO的功能傳送電子郵件,該功能可以避免爬蟲的非阻塞 IO。您可以配置傳送電子郵件的一些設定,並提供傳送附件的簡單 API。
有兩種方法可以例項化 MailSender,如下表所示 -
| 序號 | 引數 | 方法 |
|---|---|---|
| 1 | from scrapy.mail import MailSender mailer = MailSender() | 使用標準建構函式。 |
| 2 | mailer = MailSender.from_settings(settings) | 使用 Scrapy 設定物件。 |
以下行傳送不帶附件的電子郵件 -
mailer.send(to = ["receiver@example.com"], subject = "subject data", body = "body data", cc = ["list@example.com"])
MailSender 類參考
MailSender 類使用Twisted 非阻塞 IO從 Scrapy 傳送電子郵件。
class scrapy.mail.MailSender(smtphost = None, mailfrom = None, smtpuser = None, smtppass = None, smtpport = None)
下表顯示了MailSender類中使用的引數 -
| 序號 | 引數及描述 |
|---|---|
| 1 | smtphost (str) SMTP 主機用於傳送電子郵件。如果沒有,則將使用MAIL_HOST設定。 |
| 2 | mailfrom (str) 接收者的地址用於傳送電子郵件。如果沒有,則將使用MAIL_FROM設定。 |
| 3 | smtpuser 它指定 SMTP 使用者。如果未使用,則將使用MAIL_USER設定,如果未提及,則不會進行 SMTP 驗證。 |
| 4 | smtppass (str) 它指定用於驗證的 SMTP 密碼。 |
| 5 | smtpport (int) 它指定用於連線的 SMTP 埠。 |
| 6 | smtptls (boolean) 它使用 SMTP STARTTLS 實現。 |
| 7 | smtpssl (boolean) 它使用安全的 SSL 連線進行管理。 |
MailSender 類引用中存在以下兩種方法。第一種方法,
classmethod from_settings(settings)
它透過使用 Scrapy 設定物件來合併。它包含以下引數 -
settings (scrapy.settings.Settings object) - 它被視為電子郵件接收者。
另一種方法,
send(to, subject, body, cc = None, attachs = (), mimetype = 'text/plain', charset = None)
下表包含上述方法的引數 -
| 序號 | 引數及描述 |
|---|---|
| 1 | to (list) 它指的是電子郵件接收者。 |
| 2 | subject (str) 它指定電子郵件的主題。 |
| 3 | cc (list) 它指的是接收者列表。 |
| 4 | body (str) 它指的是電子郵件正文資料。 |
| 5 | attachs (iterable) 它指的是電子郵件的附件、附件的 mimetype 和附件的名稱。 |
| 6 | mimetype (str) 它表示電子郵件的 MIME 型別。 |
| 7 | charset (str) 它指定用於電子郵件內容的字元編碼。 |
郵件設定
以下設定確保無需編寫任何程式碼即可在專案中使用 MailSender 類配置電子郵件。
| 序號 | 設定和描述 | 預設值 |
|---|---|---|
| 1 | MAIL_FROM 它指的是傳送電子郵件的傳送者電子郵件。 |
'scrapy@localhost' |
| 2 | MAIL_HOST 它指的是用於傳送電子郵件的 SMTP 主機。 |
'localhost' |
| 3 | MAIL_PORT 它指定用於傳送電子郵件的 SMTP 埠。 |
25 |
| 4 | MAIL_USER 它指的是 SMTP 驗證。如果此設定設定為停用,則不會進行驗證。 |
None |
| 5 | MAIL_PASS 它提供用於 SMTP 驗證的密碼。 |
None |
| 6 | MAIL_TLS 它提供了一種使用 SSL/TLS 將不安全連線升級到安全連線的方法。 |
False |
| 7 | MAIL_SSL 它使用 SSL 加密連線實現連線。 |
False |
Scrapy - Telnet 控制檯
描述
Telnet 控制檯是一個在 Scrapy 程序內執行的 Python shell,用於檢查和控制正在執行的 Scrapy 程序。
訪問 Telnet 控制檯
可以使用以下命令訪問 telnet 控制檯:
telnet localhost 6023
基本上,telnet 控制檯列在 TCP 埠中,這在 **TELNETCONSOLE_PORT** 設定中進行了描述。
變數
下表中給出的一些預設變數用作快捷方式:
| 序號 | 快捷方式及描述 |
|---|---|
| 1 | 爬蟲 這指的是 Scrapy 爬蟲 (scrapy.crawler.Crawler) 物件。 |
| 2 | engine 這指的是 Crawler.engine 屬性。 |
| 3 | spider 這指的是當前活動的 spider。 |
| 4 | slot 這指的是引擎槽。 |
| 5 | extensions 這指的是擴充套件管理器 (Crawler.extensions) 屬性。 |
| 6 | stats 這指的是統計收集器 (Crawler.stats) 屬性。 |
| 7 | setting 這指的是 Scrapy 設定物件 (Crawler.settings) 屬性。 |
| 8 | est 這指的是列印引擎狀態報告。 |
| 9 | prefs 這指的是用於除錯的記憶體。 |
| 10 | p 這指的是 pprint.pprint 函式的快捷方式。 |
| 11 | hpy 這指的是記憶體除錯。 |
示例
以下是一些使用 Telnet 控制檯說明的示例。
暫停、恢復和停止 Scrapy 引擎
要暫停 Scrapy 引擎,請使用以下命令:
telnet localhost 6023 >>> engine.pause() >>>
要恢復 Scrapy 引擎,請使用以下命令:
telnet localhost 6023 >>> engine.unpause() >>>
要停止 Scrapy 引擎,請使用以下命令:
telnet localhost 6023 >>> engine.stop() Connection closed by foreign host.
檢視引擎狀態
Telnet 控制檯使用 **est()** 方法檢查 Scrapy 引擎的狀態,如下面的程式碼所示:
telnet localhost 6023 >>> est() Execution engine status time()-engine.start_time : 8.62972998619 engine.has_capacity() : False len(engine.downloader.active) : 16 engine.scraper.is_idle() : False engine.spider.name : followall engine.spider_is_idle(engine.spider) : False engine.slot.closing : False len(engine.slot.inprogress) : 16 len(engine.slot.scheduler.dqs or []) : 0 len(engine.slot.scheduler.mqs) : 92 len(engine.scraper.slot.queue) : 0 len(engine.scraper.slot.active) : 0 engine.scraper.slot.active_size : 0 engine.scraper.slot.itemproc_size : 0 engine.scraper.slot.needs_backout() : False
Telnet 控制檯訊號
您可以使用 telnet 控制檯訊號在 telnet 本地名稱空間中新增、更新或刪除變數。要執行此操作,您需要在處理程式中新增 telnet_vars 字典。
scrapy.extensions.telnet.update_telnet_vars(telnet_vars)
引數:
telnet_vars (dict)
其中,dict 是一個包含 telnet 變數的字典。
Telnet 設定
下表顯示了控制 Telnet 控制檯行為的設定:
| 序號 | 設定和描述 | 預設值 |
|---|---|---|
| 1 | TELNETCONSOLE_PORT 這指的是 telnet 控制檯的埠範圍。如果設定為 none,則埠將被動態分配。 |
[6023, 6073] |
| 2 | TELNETCONSOLE_HOST 這指的是 telnet 控制檯應該監聽的介面。 |
'127.0.0.1' |
Scrapy - Web 服務
描述
正在執行的 Scrapy Web 爬蟲可以透過 **JSON-RPC** 進行控制。它由 JSONRPC_ENABLED 設定啟用。此服務透過 JSON-RPC 2.0 協議提供對主爬蟲物件的訪問。訪問爬蟲物件的端點為:
https://:6080/crawler
下表包含了一些顯示 Web 服務行為的設定:
| 序號 | 設定和描述 | 預設值 |
|---|---|---|
| 1 | JSONRPC_ENABLED 這指的是布林值,它決定 Web 服務及其擴充套件是否啟用。 |
True |
| 2 | JSONRPC_LOGFILE 這指的是用於記錄對 Web 服務發出的 HTTP 請求的檔案。如果未設定,則將使用標準的 Scrapy 日誌。 |
None |
| 3 | JSONRPC_PORT 這指的是 Web 服務的埠範圍。如果設定為 none,則埠將被動態分配。 |
[6080, 7030] |
| 4 | JSONRPC_HOST 這指的是 Web 服務應該監聽的介面。 |
'127.0.0.1' |