中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Scrapy爬蟲框架的介紹和使用

發布時間:2020-06-12 15:02:49 來源:億速云 閱讀:374 作者:元一 欄目:編程語言

Scrapy簡介

Python開發的一個快速、高層次的屏幕抓取和web抓取框架,用于抓取web站點并從頁面中提取結構化的數據。Scrapy用途廣泛,可以用于數據挖掘、監測和自動化測試。

Scrapy吸引人的地方在于它是一個框架,任何人都可以根據需求方便的修改。它也提供了多種類型爬蟲的基類,如BaseSpider、sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支持。

基本功能

Scrapy是一個為遍歷爬行網站、分解獲取數據而設計的應用程序框架,它可以應用在廣泛領域:數據挖掘、信息處理和或者歷史片(歷史記錄)打包等等

盡管Scrapy原本是設計用來屏幕抓取(更精確的說,是網絡抓取)的目的,但它也可以用來訪問API來提取數據,比如Amazon的AWS或者用來當作通常目的應用的網絡蜘蛛

Scrapy框架

Scrapy是用Python實現的一個為了爬取網站數據,提取結構性數據而編寫的應用框架。可以應用在包括數據挖掘、信息處理或存儲歷史數據等一系列的程序中。

Scrapy使用Twisted基于事件的高效異步網絡框架來處理網絡通信,可以加快下載速度,不用自己去實現異步框架,并且包含了各種中間件接口,可以靈活的完成各種需求。

Scrapy架構

Scrapy爬蟲框架的介紹和使用

Scrapy Engine

  • 引擎,負責控制數據流在系統中所有組件中流動,并在相應動作發生時觸發事件。此組件相當于爬蟲的“大腦”,是整個爬蟲的調度中心

調度器(Scheduler)

  • 調度器接收從引擎發送過來的request,并將他們入隊,以便之后引擎請求他們時提供給引擎

  • 初始的爬取URL和后續在頁面中獲取的待爬取的URL將放入調度器中,等待爬取。同時調度器會自動去除重復的URL(如果特定的URL不需要去重也可以通過設置實現,如post請求的URL)

下載器(Downloader)

  • 下載器負責獲取頁面數據并提供給引擎,而后提供給spider

Spiders爬蟲

Spider是編寫的類,作用如下:

  • Scrapy用戶編寫用于分析response并提取item(即獲取到的item)

  • 額外跟進的URL,將額外跟進的URL提交給引擎,加入到Scheduler調度器中。將每個spider負責處理一個特定(或一些)網站

Item Pipeline

  • Item Pipeline負責處理被spider提取出來的item。典型的處理有清理、 驗證及持久化(例如存取到數據庫中)

  • 當頁面被爬蟲解析所需的數據存入Item后,將被發送到項目管道(Pipeline),并經過設置好次序的pipeline程序處理這些數據,最后將存入本地文件或存入數據庫

  • 類似管道 $ ls | grep test 或者類似于Django 模板中的過濾器

以下是item pipeline的一些典型應用:

  • 清理HTML數據

  • 驗證爬取的數據(檢查item包含某些字段)

  • 查重(或丟棄)

  • 將爬取結果保存到數據庫中

下載器中間件(Downloader middlewares)

簡單講就是自定義擴展下載功能的組件。

  • 下載器中間件,是在引擎和下載器之間的特定鉤子(specific hook),處理它們之間的請求request和響應response。

   它提供了一個簡便的機制,通過插入自定義代碼來擴展Scrapy功能

  • 通過設置下載器中間件可以實現爬蟲自動更換user-agent、IP等功能

Spider中間件(Spider middlewares)

Spider中間件,是在引擎和Spider之間的特定鉤子(specific hook),處理spider的輸入(response)和輸出(items或requests)。

也提供了同樣的簡便機制,通過插入自定義代碼來擴展Scrapy功能。

數據流(Data flow)

1.引擎打開一個網站(open a domain),找到處理該網站的Spider并向該spider請求第一個(批)要爬取的URL(s)

2.引擎從Spider中獲取到第一個要爬取的URL并加入到調度器(Scheduler)作為請求以備調度

3.引擎向調度器請求下一個要爬取的URL

4.調度器返回下一個要爬取的URL給引擎,引擎將URL通過下載中間件并轉發給下載器(Downloader)

5.一旦頁面下載完畢,下載器生成一個該頁面的Response,并將其通過下載中間件發送給引 擎

6.引擎從下載器中接收到Response,然后通過Spider中間件發送給Spider處理

7.Spider處理Response并返回提取到的Item及(跟進的)新的Request給引擎

8.引擎將Spider返回的Item交給Item Pipeline,將Spider返回的Request交給調度器

9.(從第二步)重復執行,直到調度器中沒有待處理的request,引擎關閉

注意:

只有當調度器中沒有任何request了,整個程序才會停止執行。如果有下載失敗的URL,會重新下載

安裝scrapy

  • 安裝wheel支持

  $ pip install wheel

  • 安裝scrapy框架

  $ pip install scrapy

  • window下,為了避免windows編譯安裝twisted依賴,安裝下面的二進制包

  $ pip install Twisted-18.4.0-cp35-cp35m-win_amd64.whl

windows下出現如下問題:

copying src\twisted\words\xish\xpathparser.g -> build\lib.win-amd64-3.5\twisted\words\xish running build_ext building 'twisted.test.raiser' extension error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools解決方案是,下載編譯好的twisted,Python Extension Packages for Windowspython3.5 下載 Twisted-18.4.0-cp35-cp35m-win_amd64.whlpython3.6 下載 Twisted-18.4.0-cp36-cp36m-win_amd64.whl安裝twisted$ pip install Twisted-18.4.0-cp35-cp35m-win_amd64.whl之后在安裝scrapy就沒有什么問題了

安裝好,使用scrapy命令看看

  1.> scrapy  2.Scrapy 1.5.0 - no active project  3.  4.Usage:  5. scrapy <command> [options] [args]  6.  7.Available commands:  8.bench Run    quick benchmark test  9.check       Check spider contracts  10.crawl       Run a spider  11.edit       Edit spider  12.fetch       Fetch a URL using the Scrapy downloader  13.genspider     Generate new spider using pre-defined templates  14.list       List available spiders  15.parse       Parse URL (using its spider) and print the results  16.runspider     Run a self-contained spider (without creating a project)  17.settings     Get settings values  18.shell       Interactive scraping console  19.startproject   Create new project  20.version     Print Scrapy version  21.view       Open URL in browser, as seen by Scrapy

                                                     Scrapy開發

項目編寫流程

1.創建項目

  使用 scrapy startproject proname 創建一個scrapy項目

  scrapy startproject <project_name> [project_dir]

2.編寫item

  在items.py中編寫Item類,明確從response中提取的item

3.編寫爬蟲

  編寫spiders/proname_spider.py,即爬取網站的spider并提取出item

4.編寫item pipeline

  item的處理,可以存儲

1 創建項目

1.1 豆瓣書評爬取

標簽為“編程”,第一頁、第二頁鏈接:

https://book.douban.com/tag/%E7%BC%96%E7%A8%8B?start=0&type=T

https://book.douban.com/tag/%E7%BC%96%E7%A8%8B?start=20&type=T

隨便找一個目錄來創建項目,執行下面命令

$ scrapy startproject first .

會產生如下目錄和文件

first ├─ scrapy.cfg └─ first   ├─ items.py   ├─ middlewares.py   ├─ pipelines.py   ├─ settings.py   ├─ __init__.py   └─ spiders     └─ __init__.py
  • first:

  外部的first目錄是整個項目目錄,內部的first目錄是整個項目的全局目錄

  • scrapy.cfg:

  必須有的重要的項目的配置文件

  • first 項目目錄

  • __init__.py 必須有,包文件

  • items.py 定義Item類,從scrapy.Item繼承,里面定義scrapy.Field類實例

  • pipelines.py 重要的是process_item()方法,處理item

  • settings.py:

  • BOT_NAME 爬蟲名

  • ROBOTSTXT_OBEY = True 是否遵從robots協議

  • USER_AGENT = '' 指定爬取時使用

  • CONCURRENT_REQEUST = 16 默認16個并行

  • DOWNLOAD_DELAY = 3 下載延時,一般要設置,不宜過快發起連續請求

  • COOKIES_ENABLED = False 缺省是啟用,一般需要登錄時才需要開啟cookie

  • SPIDER_MIDDLEWARES 爬蟲中間件

  • DOWNLOADER_MIDDLEWARES 下載中間件

  'firstscrapy.pipelines.FirstscrapyPipeline': 300item交給哪一個管道處理,300 越小優先  

   級越高

   ITEM_PIPELINES 管道配置

  'first.middlewares.FirstDownloaderMiddleware': 543543 越小優先級越高

  • spiders目錄

  __init__.py 必須有,可以在這里寫爬蟲類,也可以寫爬蟲子模塊

1.# first/settings.py參考2.BOT_NAME = 'first'3.SPIDER_MODULES = ['first.spiders']4.NEWSPIDER_MODULE = 'first.spiders'5.6.USER_AGENT = "Mozilla/5.0 (Windows NT 6.1)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36"7.ROBOTSTXT_OBEY = False8.9.DOWNLOAD_DELAY = 310.11.# Disable cookies (enabled by default)12.COOKIES_ENABLED = False

注意一定要更改User-Agent,否則訪問https://book.douban.com/會返回403

2 編寫Item

  1.在items.py中編寫  2.import scrapy  3.class BookItem(scrapy.Item):  4.title = scrapy.Field() # 書名  5.rate = scrapy.Field() # 評分

3 編寫爬蟲

為爬取豆瓣書評編寫爬蟲類,在spiders目錄下:

  • 編寫的爬蟲類需要繼承自scrapy.Spider,在這個類中定義爬蟲名、爬取范圍、其實地址等

  • 在scrapy.Spider中parse方法未實現,所以子類應該實現parse方法。該方法傳入response對象

  1.# scrapy源碼中  2.class Spider():  3.def parse(self, response): # 解析返回的內容  4.raise NotImplementedError

爬取讀書頻道,tag為“編程”的書名和評分:

https://book.douban.com/tag/%E7%BC%96%E7%A8%8B?start=20&type=T

使用模板創建spider, $ scrapy genspider -t basic book https://www.douban.com/

  1.import scrapy  2.  3.class BookSpider(scrapy.Spider): # BookSpider   4.name = 'doubanbook' # 爬蟲名,可修改,重要   5.allowed_domains = ['豆瓣'] # 爬蟲爬取范圍   6.url = '豆瓣圖書標簽: 編程'   7.start_urls = [url] # 起始URL   8.  9.# 下載器獲取了WEB Server的response就行了,parse就是解析響應的內容   10.def parse(self, response):   11. print(type(response), '~~~~~~~~~') #scrapy.http.response.html.HtmlResponse   12.print(response)   13.print('-' * 30)

使用crawl爬取子命令

   1.$ scrapy list   2.$ scrapy crawl -h   3.scrapy crawl [options] <spider>   4.   5.指定爬蟲名稱開始爬取   6.$ scrapy crawl doubanbook   7.   8.可以不打印日志   9.$ scrapy crawl doubanbook --nolog

如果在windows下運行發生twisted的異常 ModuleNotFoundError: No module named 'win32api' ,請安裝 $ pip install pywin32。

response是服務器端HTTP響應,它是scrapy.http.response.html.HtmlResponse類。

由此,修改代碼如下

   1.import scrapy   2.from scrapy.http.response.html import HtmlResponse   3.   4.class BookSpider(scrapy.Spider): # BookSpider   5. name = 'doubanbook' # 爬蟲名    6. allowed_domains = ['豆瓣'] # 爬蟲爬取范圍    7. url = '豆瓣圖書標簽: 編程'    8.start_urls = [url] # 起始URL    9.   10. # 下載器獲取了WEB Server的response就行了,parse就是解析響應的內容    11.def parse(self, response:HtmlResponse):    12. print(type(response)) #scrapy.http.response.html.HtmlResponse    13. print('-'*30)    14. print(type(response.text), type(response.body))   15.print('-'*30)   16.print(response.encoding)   17.with open('o:/testbook.html', 'w', encoding='utf-8') as f:   18. try:    19. f.write(response.text)    20. f.flush()    21. except Exception as e:    22.print(e)

3.1 解析HTML

爬蟲獲得的內容response對象,可以使用解析庫來解析。

scrapy包裝了lxml,父類TextResponse類也提供了xpath方法和css方法,可以混合使用這兩套接口解析HTML。

選擇器參考:

https://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html#id3

  1.import scrapy  2.from scrapy.http.response.html import HtmlResponse  3.  4.response = HtmlResponse('file:///O:/testbook.html', encoding='utf-8') # 構造對象  5.  6.with open('o:/testbook.html', encoding='utf8') as f:   7.response._set_body(f.read()) # 填充數據   8.#print(response.text)
  9.  1O.# 獲取所有標題及評分  11.# xpath解析   12.subjects = response.xpath('//li[@class="subject-item"]')   13.for subject in subjects:   14.title = subject.xpath('.//h3/a/text()').extract() # list   15.print(title[0].strip())  16.   17.rate = subject.xpath('.//span[@class="rating_nums"]/text()').extract()  18.print(rate[0].strip())   19.  2O.print('-'*30)   21.# css解析   22.subjects = response.css('li.subject-item')   23.for subject in subjects:   24.title = subject.css('h3 a::text').extract()   25.print(title[0].strip())   26.  27.rate = subject.css('span.rating_nums::text').extract()   28.print(rate[0].strip())   29.print('-'*30)  30.   31. # xpath和css混合使用、正則表達式匹配   32.subjects = response.css('li.subject-item')   33.for subject in subjects:  34.# 提取鏈接  35.href =subject.xpath('.//h3').css('a::attr(href)').extract()  36.print(href[0])  37.  38. # 使用正則表達式  39.id = subject.xpath('.//h3/a/@href').re(r'\d*99\d*')  40.if id:   41.print(id[0])   42.  43.# 要求顯示9分以上數據   44.rate = subject.xpath('.//span[@class="rating_nums"]/text()').re(r'^9.*')   45.# rate = subject.css('span.rating_nums::text').re(r'^9\..*')   46.if rate:   47.print(rate)

3.2 item封裝數據

   1.# spiders/bookspider.py   2.import scrapy   3.from scrapy.http.response.html import HtmlResponse   4.from ..items import BookItem   5.   6.class BookSpider(scrapy.Spider): # BookSpider   7.name = 'doubanbook' # 爬蟲名    8.allowed_domains = ['豆瓣'] # 爬蟲爬取范圍    9.url = '豆瓣圖書標簽: 編程'   10.start_urls = [url] # 起始URL   11.   12. # 下載器獲取了WEB Server的response就行了,parse就是解析響應的內容    13.def parse(self, response:HtmlResponse):    14.items = []    15.# xpath解析    16.subjects = response.xpath('//li[@class="subject-item"]')    17.for subject in subjects:    18.title = subject.xpath('.//h3/a/text()').extract()        19.rate = subject.xpath('.//span[@class="rating_nums"]/text()').extract_first()        20.item = BookItem()        21.item['title'] = title[0].strip()        22.item['rate'] = rate.strip()        23. items.append(item)   24.     25. print(items)   26.   27.return items # 一定要return,否則保存不下來   28.    29.# 使用命令保存return的數據   30.# scrapy crawl -h   31.# --output=FILE, -o FILE dump scraped items into FILE (use - for stdout)   32.# 文件擴展名支持'json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle'   33.# scrapy crawl doubanbook -o dbbooks.json

得到下圖數

Scrapy爬蟲框架的介紹和使用

注意上圖的數據已經是unicode字符,漢字的unicode表達。

4 pipeline處理

將bookspider.py中BookSpider改成生成器,只需要把 return items 改造成 yield item ,即由產生一個列表變成yield一個個item

腳手架幫我們創建了一個pipelines.py文件和一個類

4.1 開啟pipeline

  1.# Configure item pipelines  2.# See Item Pipeline - Scrapy 1.8.0 documentation  3.ITEM_PIPELINES = {  4.'first.pipelines.FirstPipeline': 300,  5.}

整數300表示優先級,越小越高。

取值范圍為0-1000

4.2常用方法

   1.class FirstPipeline(object):    2.def __init__(self): # 全局設置    3. print('~~~~~~~~~~ init ~~~~~~~~~~~~')    4.    5.def open_spider(self, spider): # 當某spider開啟時調用    6. print(spider,'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')    7.   8.def process_item(self, item, spider):    9. # item 獲取的item;spider 獲取該item的spider    10.return item    11.   12.def close_spider(self, spider): # 當某spider關閉時調用    13.print(spider,'========================================')   14.

需求

通過pipeline將爬取的數據存入json文件中

   1.# spider/bookspider.py   2.import scrapy   3.from scrapy.http.response.html import HtmlResponse   4.from ..items import BookItem   5.   6.class BookSpider(scrapy.Spider): # BookSpider   7. name = 'doubanbook' # 爬蟲名    8. allowed_domains = ['豆瓣'] # 爬蟲爬取范圍    9.url = '豆瓣圖書標簽: 編程'    10. start_urls = [url] # 起始URL   11.   12.# spider上自定義配置信息    13.custom_settings = {    14. 'filename' : 'o:/books.json'   15. }   16.# 下載器獲取了WEB Server的response就行了,parse就是解析響應的內容   17.def parse(self, response:HtmlResponse):   18. #items = []    19.# xpath解析    20.subjects = response.xpath('//li[@class="subject-item"]')    21.for subject in subjects:   22.title = subject.xpath('.//h3/a/text()').extract()    23.rate =subject.xpath('.//span[@class="rating_nums"]/text()').extract_first()    24.item = BookItem()    25.item['title'] = title[0].strip()    26.item['rate'] = rate.strip()    27.#items.append(item)   28.   29.yield item    30.#return items   31.   32.# pipelines.py
   33.import simplejson as json
   34.
   35.class FirstPipeline(object):    36. def __init__(self): # 全局設置    37. print('~~~~~~~~~~ init ~~~~~~~~~~~~')   38.   39.def open_spider(self, spider): # 當某spider開啟時調用    40. print('{} ~~~~~~~~~~~~~~~~~~~~'.format(spider))    41. print(spider.settings.get('filename'))    42.self.file = open(spider.settings['filename'], 'w', encoding='utf-8')    43.self.file.write('[\n')   44.    45.def process_item(self, item, spider):    46.# item 獲取的item;spider 獲取該item的spider    47.self.file.write(json.dumps(dict(item)) + ',\n')    48.return item   49.   50.def close_spider(self, spider): # 當某spider關閉時調用   51.self.file.write(']')    52.self.file.close()    53.print('{} ======================='.format(spider))    54.print('-'*30)

5 url提取

如果要爬取下一頁內容,可以自己分析每一頁的頁碼變化,也可以通過提取分頁欄的鏈接

   1.# spider/bookspider.py   2.import scrapy   3.from scrapy.http.response.html import HtmlResponse   4.from ..items import BookItem   5.   6.class BookSpider(scrapy.Spider): # BookSpider    7.name = 'doubanbook' # 爬蟲名   8.allowed_domains = ['豆瓣'] # 爬蟲爬取范圍   9.url = '豆瓣圖書標簽: 編程'    10.start_urls = [url] # 起始URL   11.   12.# spider上自定義配置信息    13.custom_settings = {      14.'filename' : 'o:/books.json'   15.}   16.   17.# 下載器獲取了WEB Server的response就行了,parse就是解析響應的內容      18.def parse(self, response:HtmlResponse):    19.#items = []      20.# xpath解析      21.# 獲取下一頁,只是測試,所以使用re來控制頁碼    22.print('-' * 30)   23.urls = response.xpath('//div[@class="paginator"]/span[@class="next"]/a/@href').re(   24.          r'.*start=[24]\d[^\d].*')    25.print(urls)   26.print('-' * 30)   27.yield from (scrapy.Request(response.urljoin(url)) for url in urls)      28.print('++++++++++++++++++++++++')   29.    30.subjects = response.xpath('//li[@class="subject-item"]')    31.for subject in subjects:   32.# 解決圖書副標題拼接    33.title = "".join(map(lambda x:x.strip(), subject.xpath('.//h3/a//text()').extract()))    34.rate = subject.xpath('.//span[@class="rating_nums"]/text()').extract_first()    35.#print(rate) # 有的沒有評分,要注意可能返回None   36.   37.item = BookItem()   38.item['title'] = title   39.item['rate'] = rate    40.#items.append(item)    41.yield item   42.    43.#return items
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

璧山县| 呼和浩特市| 台中县| 讷河市| 安岳县| 兴山县| 平阴县| 邵东县| 辽阳县| 诸城市| 辉县市| 沐川县| 五指山市| 东兰县| 永州市| 寿光市| 潜山县| 凤城市| 台湾省| 信阳市| 新河县| 柳州市| 皮山县| 六枝特区| 云浮市| 汽车| 万荣县| 浠水县| 基隆市| 酉阳| 荣成市| 吉首市| 高州市| 湖北省| 德化县| 哈尔滨市| 墨玉县| 白玉县| 图木舒克市| 景德镇市| 峨眉山市|