激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python的爬蟲程序編寫框架Scrapy入門學習教程

Python的爬蟲程序編寫框架Scrapy入門學習教程

2020-08-31 11:39Andrew_liu Python

Python的一大優勢就是可以輕松制作Web爬蟲,而超高人氣的Scrapy則是名副其實的Python編寫爬蟲的利器,這里我們就來看一下Python的爬蟲程序編寫框架Scrapy入門學習教程:

1. Scrapy簡介
Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。 可以應用在包括數據挖掘,信息處理或存儲歷史數據等一系列的程序中。
其最初是為了頁面抓取 (更確切來說, 網絡抓取 )所設計的, 也可以應用在獲取API所返回的數據(例如 Amazon Associates Web Services ) 或者通用的網絡爬蟲。Scrapy用途廣泛,可以用于數據挖掘、監測和自動化測試
Scrapy 使用了 Twisted異步網絡庫來處理網絡通訊。整體架構大致如下

Python的爬蟲程序編寫框架Scrapy入門學習教程

Scrapy主要包括了以下組件:

(1)引擎(Scrapy): 用來處理整個系統的數據流處理, 觸發事務(框架核心)

(2)調度器(Scheduler): 用來接受引擎發過來的請求, 壓入隊列中, 并在引擎再次請求的時候返回. 可以想像成一個URL(抓取網頁的網址或者說是鏈接)的優先隊列, 由它來決定下一個要抓取的網址是什么, 同時去除重復的網址

(3)下載器(Downloader): 用于下載網頁內容, 并將網頁內容返回給蜘蛛(Scrapy下載器是建立在twisted這個高效的異步模型上的)

(4)爬蟲(Spiders): 爬蟲是主要干活的, 用于從特定的網頁中提取自己需要的信息, 即所謂的實體(Item)。用戶也可以從中提取出鏈接,讓Scrapy繼續抓取下一個頁面

項目管道(Pipeline): 負責處理爬蟲從網頁中抽取的實體,主要的功能是持久化實體、驗證實體的有效性、清除不需要的信息。當頁面被爬蟲解析后,將被發送到項目管道,并經過幾個特定的次序處理數據。

(5)下載器中間件(Downloader Middlewares): 位于Scrapy引擎和下載器之間的框架,主要是處理Scrapy引擎與下載器之間的請求及響應。

(6)爬蟲中間件(Spider Middlewares): 介于Scrapy引擎和爬蟲之間的框架,主要工作是處理蜘蛛的響應輸入和請求輸出。

(7)調度中間件(Scheduler Middewares): 介于Scrapy引擎和調度之間的中間件,從Scrapy引擎發送到調度的請求和響應。

Scrapy運行流程大概如下:

首先,引擎從調度器中取出一個鏈接(URL)用于接下來的抓取
引擎把URL封裝成一個請求(Request)傳給下載器,下載器把資源下載下來,并封裝成應答包(Response)
然后,爬蟲解析Response
若是解析出實體(Item),則交給實體管道進行進一步的處理。
若是解析出的是鏈接(URL),則把URL交給Scheduler等待抓取

2. 安裝Scrapy
使用以下命令:

sudo pip install virtualenv #安裝虛擬環境工具
virtualenv ENV #創建一個虛擬環境目錄
source ./ENV/bin/active #激活虛擬環境
pip install Scrapy
#驗證是否安裝成功
pip list
#輸出如下
cffi (0.8.6)
cryptography (0.6.1)
cssselect (0.9.1)
lxml (3.4.1)
pip (1.5.6)
pycparser (2.10)
pyOpenSSL (0.14)
queuelib (1.2.2)
Scrapy (0.24.4)
setuptools (3.6)
six (1.8.0)
Twisted (14.0.2)
w3lib (1.10.0)
wsgiref (0.1.2)
zope.interface (4.1.1)

更多虛擬環境的操作可以查看我的博文

3. Scrapy Tutorial
在抓取之前, 你需要新建一個Scrapy工程. 進入一個你想用來保存代碼的目錄,然后執行:

$ scrapy startproject tutorial

這個命令會在當前目錄下創建一個新目錄 tutorial, 它的結構如下:

.
├── scrapy.cfg
└── tutorial
 ├── __init__.py
 ├── items.py
 ├── pipelines.py
 ├── settings.py
 └── spiders
  └── __init__.py

這些文件主要是:

(1)scrapy.cfg: 項目配置文件
(2)tutorial/: 項目python模塊, 之后您將在此加入代碼
(3)tutorial/items.py: 項目items文件
(4)tutorial/pipelines.py: 項目管道文件
(5)tutorial/settings.py: 項目配置文件
(6)tutorial/spiders: 放置spider的目錄

3.1. 定義Item
Items是將要裝載抓取的數據的容器,它工作方式像 python 里面的字典,但它提供更多的保護,比如對未定義的字段填充以防止拼寫錯誤

通過創建scrapy.Item類, 并且定義類型為 scrapy.Field 的類屬性來聲明一個Item.
我們通過將需要的item模型化,來控制從 dmoz.org 獲得的站點數據,比如我們要獲得站點的名字,url 和網站描述,我們定義這三種屬性的域。在 tutorial 目錄下的 items.py 文件編輯

from scrapy.item import Item, Field


class DmozItem(Item):
 # define the fields for your item here like:
 name = Field()
 description = Field()
 url = Field()

3.2. 編寫Spider
Spider 是用戶編寫的類, 用于從一個域(或域組)中抓取信息, 定義了用于下載的URL的初步列表, 如何跟蹤鏈接,以及如何來解析這些網頁的內容用于提取items。

要建立一個 Spider,繼承 scrapy.Spider 基類,并確定三個主要的、強制的屬性:

name:爬蟲的識別名,它必須是唯一的,在不同的爬蟲中你必須定義不同的名字.
start_urls:包含了Spider在啟動時進行爬取的url列表。因此,第一個被獲取到的頁面將是其中之一。后續的URL則從初始的URL獲取到的數據中提取。我們可以利用正則表達式定義和過濾需要進行跟進的鏈接。
parse():是spider的一個方法。被調用時,每個初始URL完成下載后生成的 Response 對象將會作為唯一的參數傳遞給該函數。該方法負責解析返回的數據(response data),提取數據(生成item)以及生成需要進一步處理的URL的 Request 對象。
這個方法負責解析返回的數據、匹配抓取的數據(解析為 item )并跟蹤更多的 URL。
在 /tutorial/tutorial/spiders 目錄下創建 dmoz_spider.py

import scrapy

class DmozSpider(scrapy.Spider):
 name = "dmoz"
 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]
  with open(filename, 'wb') as f:
   f.write(response.body)

3.3. 爬取
當前項目結構

├── scrapy.cfg
└── tutorial
 ├── __init__.py
 ├── items.py
 ├── pipelines.py
 ├── settings.py
 └── spiders
  ├── __init__.py
  └── dmoz_spider.py

到項目根目錄, 然后運行命令:

$ scrapy crawl dmoz

運行結果:
2014-12-15 09:30:59+0800 [scrapy] INFO: Scrapy 0.24.4 started (bot: tutorial)
2014-12-15 09:30:59+0800 [scrapy] INFO: Optional features available: ssl, http11
2014-12-15 09:30:59+0800 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'tutorial.spiders', 'SPIDER_MODULES': ['tutorial.spiders'], 'BOT_NAME': 'tutorial'}
2014-12-15 09:30:59+0800 [scrapy] INFO: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
2014-12-15 09:30:59+0800 [scrapy] INFO: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats
2014-12-15 09:30:59+0800 [scrapy] INFO: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware
2014-12-15 09:30:59+0800 [scrapy] INFO: Enabled item pipelines:
2014-12-15 09:30:59+0800 [dmoz] INFO: Spider opened
2014-12-15 09:30:59+0800 [dmoz] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2014-12-15 09:30:59+0800 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023
2014-12-15 09:30:59+0800 [scrapy] DEBUG: Web service listening on 127.0.0.1:6080
2014-12-15 09:31:00+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None)
2014-12-15 09:31:00+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None)
2014-12-15 09:31:00+0800 [dmoz] INFO: Closing spider (finished)
2014-12-15 09:31:00+0800 [dmoz] INFO: Dumping Scrapy stats:
 {'downloader/request_bytes': 516,
  'downloader/request_count': 2,
  'downloader/request_method_count/GET': 2,
  'downloader/response_bytes': 16338,
  'downloader/response_count': 2,
  'downloader/response_status_count/200': 2,
  'finish_reason': 'finished',
  'finish_time': datetime.datetime(2014, 12, 15, 1, 31, 0, 666214),
  'log_count/DEBUG': 4,
  'log_count/INFO': 7,
  'response_received_count': 2,
  'scheduler/dequeued': 2,
  'scheduler/dequeued/memory': 2,
  'scheduler/enqueued': 2,
  'scheduler/enqueued/memory': 2,
  'start_time': datetime.datetime(2014, 12, 15, 1, 30, 59, 533207)}
2014-12-15 09:31:00+0800 [dmoz] INFO: Spider closed (finished)

3.4. 提取Items
3.4.1. 介紹Selector

從網頁中提取數據有很多方法。Scrapy使用了一種基于 XPath 或者 CSS 表達式機制: Scrapy Selectors

出XPath表達式的例子及對應的含義:

  • /html/head/title: 選擇HTML文檔中 <head> 標簽內的 <title> 元素
  • /html/head/title/text(): 選擇 <title> 元素內的文本
  • //td: 選擇所有的 <td> 元素
  • //div[@class="mine"]: 選擇所有具有class="mine" 屬性的 div 元素

等多強大的功能使用可以查看XPath tutorial

為了方便使用 XPaths,Scrapy 提供 Selector 類, 有四種方法 :

  • xpath():返回selectors列表, 每一個selector表示一個xpath參數表達式選擇的節點.
  • css() : 返回selectors列表, 每一個selector表示CSS參數表達式選擇的節點
  • extract():返回一個unicode字符串,該字符串為XPath選擇器返回的數據
  • re(): 返回unicode字符串列表,字符串作為參數由正則表達式提取出來

3.4.2. 取出數據

  • 首先使用谷歌瀏覽器開發者工具, 查看網站源碼, 來看自己需要取出的數據形式(這種方法比較麻煩), 更簡單的方法是直接對感興趣的東西右鍵審查元素, 可以直接查看網站源碼

在查看網站源碼后, 網站信息在第二個<ul>內

<ul class="directory-url" style="margin-left:0;">

 <li><a href="http://www.pearsonhighered.com/educator/academic/product/0,,0130260363,00%2Ben-USS_01DBC.html" class="listinglink">Core Python Programming</a> 
- By Wesley J. Chun; Prentice Hall PTR, 2001, ISBN 0130260363. For experienced developers to improve extant skills; professional level examples. Starts by introducing syntax, objects, error handling, functions, classes, built-ins. [Prentice Hall]
<div class="flag"><a href="/public/flag?cat=Computers%2FProgramming%2FLanguages%2FPython%2FBooks&url=http%3A%2F%2Fwww.pearsonhighered.com%2Feducator%2Facademic%2Fproduct%2F0%2C%2C0130260363%2C00%252Ben-USS_01DBC.html"><img src="/img/flag.png" link = sel.xpath('a/@href').extract()
 desc = sel.xpath('text()').extract()
 print title, link, desc

在已有的爬蟲文件中修改代碼

import scrapy

class DmozSpider(scrapy.Spider):
 name = "dmoz"
 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'):
   link = sel.xpath('a/@href').extract()
   desc = sel.xpath('text()').extract()
   print title, link, desc

3.4.3. 使用item
Item對象是自定義的python字典,可以使用標準的字典語法來獲取到其每個字段的值(字段即是我們之前用Field賦值的屬性)

>>> item = DmozItem()
>>> item['title'] = 'Example title'
>>> item['title']
'Example title'

一般來說,Spider將會將爬取到的數據以 Item 對象返回, 最后修改爬蟲類,使用 Item 來保存數據,代碼如下

from scrapy.spider import Spider
from scrapy.selector import Selector
from tutorial.items import DmozItem


class DmozSpider(Spider):
 name = "dmoz"
 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):
  sel = Selector(response)
  sites = sel.xpath('//ul[@class="directory-url"]/li')
  items = []

  for site in sites:
   item = DmozItem()
   item['name'] = site.xpath('a/text()').extract()
   item['url'] = site.xpath('a/@href').extract()
   item['description'] = site.xpath('text()').re('-\s[^\n]*\\r')
   items.append(item)
  return items

3.5. 使用Item Pipeline
當Item在Spider中被收集之后,它將會被傳遞到Item Pipeline,一些組件會按照一定的順序執行對Item的處理。
每個item pipeline組件(有時稱之為ItemPipeline)是實現了簡單方法的Python類。他們接收到Item并通過它執行一些行為,同時也決定此Item是否繼續通過pipeline,或是被丟棄而不再進行處理。
以下是item pipeline的一些典型應用:

  • 清理HTML數據
  • 驗證爬取的數據(檢查item包含某些字段)
  • 查重(并丟棄)
  • 將爬取結果保存,如保存到數據庫、XML、JSON等文件中

編寫你自己的item pipeline很簡單,每個item pipeline組件是一個獨立的Python類,同時必須實現以下方法:

(1)process_item(item, spider)  #每個item pipeline組件都需要調用該方法,這個方法必須返回一個 Item (或任何繼承類)對象,或是拋出 DropItem異常,被丟棄的item將不會被之后的pipeline組件所處理。

#參數:

item: 由 parse 方法返回的 Item 對象(Item對象)

spider: 抓取到這個 Item 對象對應的爬蟲對象(Spider對象)

(2)open_spider(spider)  #當spider被開啟時,這個方法被調用。

#參數:

spider : (Spider object) – 被開啟的spider

(3)close_spider(spider)  #當spider被關閉時,這個方法被調用,可以再爬蟲關閉后進行相應的數據處理。

#參數:

spider : (Spider object) – 被關閉的spider

為JSON文件編寫一個items

from scrapy.exceptions import DropItem

class TutorialPipeline(object):

 # put all words in lowercase
 words_to_filter = ['politics', 'religion']

 def process_item(self, item, spider):
  for word in self.words_to_filter:
   if word in unicode(item['description']).lower():
    raise DropItem("Contains forbidden word: %s" % word)
  else:
   return item

在 settings.py 中設置ITEM_PIPELINES激活item pipeline,其默認為[]

ITEM_PIPELINES = {'tutorial.pipelines.FilterWordsPipeline': 1}

3.6. 存儲數據
使用下面的命令存儲為json文件格式

scrapy crawl dmoz -o items.json

4.示例
4.1最簡單的spider(默認的Spider)

用實例屬性start_urls中的URL構造Request對象
框架負責執行request
將request返回的response對象傳遞給parse方法做分析

簡化后的源碼:

class Spider(object_ref):
 """Base class for scrapy spiders. All spiders must inherit from this
 class.
 """
 
 name = None
 
 def __init__(self, name=None, **kwargs):
  if name is not None:
   self.name = name
  elif not getattr(self, 'name', None):
   raise ValueError("%s must have a name" % type(self).__name__)
  self.__dict__.update(kwargs)
  if not hasattr(self, 'start_urls'):
   self.start_urls = []
 
 def start_requests(self):
  for url in self.start_urls:
   yield self.make_requests_from_url(url)
 
 def make_requests_from_url(self, url):
  return Request(url, dont_filter=True)
 
 def parse(self, response):
  raise NotImplementedError
 
 
BaseSpider = create_deprecated_class('BaseSpider', Spider)

一個回調函數返回多個request的例子

import scrapyfrom myproject.items import MyItemclass MySpider(scrapy.Spider):
 name = 'example.com'
 allowed_domains = ['example.com']
 start_urls = [
  'http://www.example.com/1.html',
  'http://www.example.com/2.html',
  'http://www.example.com/3.html',
 ]
 
 def parse(self, response):
  sel = scrapy.Selector(response)
  for h3 in response.xpath('//h3').extract():
   yield MyItem(title=h3)
 
  for url in response.xpath('//a/@href').extract():
   yield scrapy.Request(url, callback=self.parse)

構造一個Request對象只需兩個參數: URL和回調函數

4.2CrawlSpider
通常我們需要在spider中決定:哪些網頁上的鏈接需要跟進, 哪些網頁到此為止,無需跟進里面的鏈接。CrawlSpider為我們提供了有用的抽象——Rule,使這類爬取任務變得簡單。你只需在rule中告訴scrapy,哪些是需要跟進的。
回憶一下我們爬行mininova網站的spider.

class MininovaSpider(CrawlSpider):
 name = 'mininova'
 allowed_domains = ['mininova.org']
 start_urls = ['http://www.mininova.org/yesterday']
 rules = [Rule(LinkExtractor(allow=['/tor/\d+']), 'parse_torrent')]
 
 def parse_torrent(self, response):
  torrent = TorrentItem()
  torrent['url'] = response.url
  torrent['name'] = response.xpath("//h1/text()").extract()
  torrent['description'] = response.xpath("//div[@id='description']").extract()
  torrent['size'] = response.xpath("//div[@id='specifications']/p[2]/text()[2]").extract()
  return torrent

上面代碼中 rules的含義是:匹配/tor/\d+的URL返回的內容,交給parse_torrent處理,并且不再跟進response上的URL。
官方文檔中也有個例子:

 rules = (
  # 提取匹配 'category.php' (但不匹配 'subsection.php') 的鏈接并跟進鏈接(沒有callback意味著follow默認為True)
  Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),
 
  # 提取匹配 'item.php' 的鏈接并使用spider的parse_item方法進行分析
  Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),
 )

除了Spider和CrawlSpider外,還有XMLFeedSpider, CSVFeedSpider, SitemapSpider

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩黄在线观看 | 综合成人在线 | 亚洲国产精品久久久久久久久久久 | 久色免费| 久久久中精品2020中文 | 在线日韩av电影 | 海外中文字幕在线观看 | 色中色综合 | 法国极品成人h版 | 成人精品免费看 | 久久久久久久一区 | 久草在线资源视频 | 国产午夜精品一区二区三区四区 | 成人午夜在线免费观看 | 国产99久久久久久免费看农村 | 毛片免费观看视频 | 欧美一a一片一级一片 | 中文字幕欧美视频 | 国产无遮挡一区二区三区毛片日本 | 国产午夜精品久久久久婷 | 色吧久久 | 国产一区二区在线观看视频 | 欧美一级网 | 《97色伦在色在线播放》 | 免费观看黄色片视频 | 久久人人爽人人爽人人片av高清 | 欧美一级黑人 | 国产精品一区二区视频 | 久久蜜桃精品一区二区三区综合网 | 免费看性xxx高清视频自由 | 久久国产一级 | 污污黄| 91福利免费视频 | 日韩av成人 | 亚洲第一精品在线 | 毛片免费观看日本中文 | 欧美男女爱爱视频 | 亚洲一区二区网址 | 成人免费自拍视频 | 欧美激情性色生活片在线观看 | 亚洲精品一区二区三区大胸 |