Python3 Scrapy爬蟲框架-使用


  • 創建Scrapy項目
1 # https://github.com/My-Sun-Shine/Python/tree/master/Python3/Scrapy_Learn/Scrapy_A
2 scrapy startproject Scrapy_A
  • 項目結構:  
    • scrapy.cfg:Scrapy項目的配置文件,定義了項目文件路徑、不算
    • Scrapy_A:項目的模塊,需要從這里引入
      • spiders:其中包括一個個Spider的實現,每個Spider都有一個文件
      • items.py:定義Item數據結構,存放所有的Item的定義,定義爬取的數據結構
      • middlewares.py:定義爬取時的中間件,定義Spider Middlewares和Downloader Middlewares的實現
      • pipelines.py:定義數據管道,定義Item Pipeline的實現存放所有的Item Pipeline的實現
      • settings.py:定義項目的全局配置
  • 創建爬蟲:進入到Scrapy_A文件中,使用命名行創建一個Spider
 1 # 創建quotes.py這個Spider
 2 scrapy genspider quotes quotes.toscrape.com 
 3 # quotes.py
 4 # -*- coding: utf-8 -*-
 5 import scrapy
 6 
 7 class QuotesSpider(scrapy.Spider):
 8     name = 'quotes'                # 項目的唯一名字,區分不同的Spider
 9     allowed_domains = ['quotes.toscrape.com']     # 允許爬取的域名,如果初始或后續的請求鏈接不是這個域名下的,則請求鏈接會被過濾掉
10     start_urls = ['http://quotes.toscrape.com/'] # 爬蟲啟動時爬取的url列表,初始請求由它來定義
11     
12     def parse(self, response):    # 該方法負責解析返回的響應、提取數據或者進一步生成要處理的請求
13         """默認情況下,在start_urls里面的鏈接構成的請求完成下載執行后,返回的響應就會作為唯一參數傳給該函數"""
14         pass
  • 創建Item:Item是保存爬取數據的容器
1 # items.py
2 import scrapy
3 
4 class QuoteItem(scrapy.Item):
5     """創建Item需要繼承scrapy.Item類,定義類型scrapy.Field字段"""
6     text = scrapy.Field()
7     author = scrapy.Field()
8     tags = scrapy.Field()
  • 進行爬蟲解析,編寫QuotesSpider
 1 # quotes.py
 2 import scrapy
 3 from Scrapy_A.items import QuoteItem
 4 
 5 class QuotesSpider(scrapy.Spider):
 6     name = 'quotes'
 7     allowed_domains = ['quotes.toscrape.com']
 8     start_urls = ['http://quotes.toscrape.com/']
 9     
10     def parse(self, response):
11         """response是start_urls里面的鏈接爬取后的結果,使用parse()方法進行解析,使用CSS選擇器或者XPath選擇器"""
12         quotes = response.css('.quote')
13         for quote in quotes:
14             item = QuoteItem() # 聲明數據類Item
15             # extract_first()方法獲取第一個元素;extract()方法獲取所有結果組成的列表
16             item['text'] = quote.css('.text::text').extract_first()
17             item['text'] = quote.css('.author::text').extract_first()
18             item['tags'] = quote.css('.tags .tag::text').extract()
19             yield item
20             
21         next_page = response.css('.pager .next a::attr("href")').extract_first() # 獲取下一頁
22         url = response.urljoin(next_page)
23         # url:請求鏈接;callback:回調函數,當得到url響應的時候,回調parse()方法
24         yield scrapy.Request(url=url, callback=self.parse)
  • 運行爬蟲
 1 scrapy crawl quotes               # 爬取結果顯示到控制台上
 2 scrapy crawl quotes -o quotes.json       # 爬取結果保存在JSON文件中
 3 scrapy crawl quotes -o quotes.jl         # 每一個Item輸出一行JSON,jl是jsonlines的縮寫
 4 scrapy crawl quotes -o quotes.jsonlines  # 每一個Item輸出一行JSON
 5 scrapy crawl quotes -o quotes.csv        # 爬取結果保存在CSV文件中
 6 scrapy crawl quotes -o quotes.xml        # 爬取結果保存在XML文件中
 7 scrapy crawl quotes -o quotes.pickle     # 爬取結果保存在Pickle文件中
 8 scrapy crawl quotes -o quotes.marshal    # 爬取結果保存在marshal格式文件中
 9 # ftp遠程輸出,需要配置用戶名,密碼,地址,輸出路徑
10 scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv
  • 使用Item Pipeline:Item Pipeline為項目管道,當Item生成后,它會自動被傳送到Item Pipeline進行處理(清理HTML數據、驗證爬取數據、檢測爬取字段、查重並丟棄重復內容、將爬取結果保存到數據庫)
 1 # pipelines.py
 2 # -*- coding: utf-8 -*-
 3 from scrapy.exceptions import DropItem
 4 import pymongo
 5 
 6 class TextPipeline(object):
 7     def __init__(self):
 8         self.limit = 50
 9         
10     def process_item(self, item, spider):
11         """該方法必須返回包含數據的字典或Item對象或者拋出異常;item:每次爬蟲生成的Item對象;spider:爬蟲實例"""
12         if item['text']:
13             if len(item['text']) > self.limit:
14                 item['text'] = item['text'][0:self.limit].strip() + '...'
15             return item
16         else:
17             return DropItem("Missing Text")
18         
19 class MongoPipeline(object): # 存入數據庫
20     def __init__(self, mongo_uri, mongo_db):
21         self.mongo_uri = mongo_uri  # 鏈接
22         self.mongo_db = mongo_db  # 數據庫名
23         
24     @classmethod  # 標識這是一個依賴注入的方式
25     def from_crawler(cls, crawler):
26         """:param crawler: 得到全局配置的每個配置信息來自settings.py"""
27         return cls(
28             mongo_uri=crawler.settings.get('MONGO_URI'),
29             mongo_db=crawler.settings.get('MONGO_DB')
30         )
31     
32     def open_spider(self, spider): # 當爬蟲開啟的時候,這個方法被調用
33         self.client = pymongo.MongoClient(self.mongo_uri)
34         self.db = self.client[self.mongo_db]
35         
36     def process_item(self, item, spider): # 實現數據插入
37         name = item.__class__.__name__
38         self.db[name].insert(dict(item))
39         return item
40     
41     def close_spider(self, spider): # 爬蟲關閉的時候,該方法被調用
42         self.client.close()
  • 配置對應Item Pipeline的settings.py
1 # settings.py
2 # 鍵名是Pipeline的類名稱,鍵值是調用優先級,數字越小則對應的Pipeline越先被調用
3 ITEM_PIPELINES = {
4     'Scrapy_A.pipelines.TextPipeline': 300,
5     'Scrapy_A.pipelines.MongoPipeline': 400,
6 }
7 MONGO_URL = 'localhost'
8 MONGO_DB = 'Scrapy_A'
  • 再次運行爬蟲
  • Spider運行流程:Spider類定義了如何爬取某個網站的流程和解析方式
    • 以初始的URL初始化Request,並設置回調函數,當Request成功請求並返回時,Response生成並作為參數傳給該回調函數
    • 在回調函數中分析返回的網頁內容,返回的結果有兩種形式:一種是解析到的有效結果返回字典或Item對象,它們可以經過處理或者直接保存;另外一種就是解析得到下一頁的鏈接,可以利用該鏈接構造Request並設置新的回調函數,返回Request等待后續流程
    • 如果返回的是字典或Item對象,通過Feed Exports等組件將返回結果存入到文件,如果設置了Pipline的話,可以使用Pipline處理(如過濾、修正)並保存
    • 如果返回的是Request,那么Request執行成功得到Response之后,Response會被傳遞給Request中定義的回調函數,在回調函數中可以使用選擇器來分析新得到的網頁內容,並根據分析的數據生成Item
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM