scrapy之spiders
生活随笔
收集整理的這篇文章主要介紹了
scrapy之spiders
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、介紹
#1、Spiders是由一系列類(定義了一個網址或一組網址將被爬取)組成,具體包括如何執行爬取任務并且如何從頁面中提取結構化的數據。#2、換句話說,Spiders是你為了一個特定的網址或一組網址自定義爬取和解析頁面行為的地方2、Spiders會循環做如下事情
#1、生成初始的Requests來爬取第一個URLS,并且標識一個回調函數 第一個請求定義在start_requests()方法內默認從start_urls列表中獲得url地址來生成Request請求,默認的回調函數是parse方法?;卣{函數在下載完成返回response時自動觸發#2、在回調函數中,解析response并且返回值 返回值可以4種:包含解析數據的字典Item對象新的Request對象(新的Requests也需要指定一個回調函數)或者是可迭代對象(包含Items或Request)#3、在回調函數中解析頁面內容 通常使用Scrapy自帶的Selectors,但很明顯你也可以使用Beutifulsoup,lxml或其他你愛用啥用啥。#4、最后,針對返回的Items對象將會被持久化到數據庫 通過Item Pipeline組件存到數據庫:https://docs.scrapy.org/en/latest/topics/item-pipeline.html#topics-item-pipeline) 或者導出到不同的文件(通過Feed exports:https://docs.scrapy.org/en/latest/topics/feed-exports.html#topics-feed-exports)3、Spiders總共提供了五種類:
#1、scrapy.spiders.Spider #scrapy.Spider等同于scrapy.spiders.Spider #2、scrapy.spiders.CrawlSpider #3、scrapy.spiders.XMLFeedSpider #4、scrapy.spiders.CSVFeedSpider #5、scrapy.spiders.SitemapSpider4、導入使用
# -*- coding: utf-8 -*- import scrapy from scrapy.spiders import Spider,CrawlSpider,XMLFeedSpider,CSVFeedSpider,SitemapSpiderclass AmazonSpider(scrapy.Spider): #自定義類,繼承Spiders提供的基類name = 'amazon'allowed_domains = ['www.amazon.cn']start_urls = ['http://www.amazon.cn/']def parse(self, response):pass5、class scrapy.spiders.Spider
這是最簡單的spider類,任何其他的spider類都需要繼承它(包含你自己定義的)。
該類不提供任何特殊的功能,它僅提供了一個默認的start_requests方法默認從start_urls中讀取url地址發送requests請求,并且默認parse作為回調函數
class AmazonSpider(scrapy.Spider):name = 'amazon' allowed_domains = ['www.amazon.cn'] start_urls = ['http://www.amazon.cn/']custom_settings = {'BOT_NAME' : 'Egon_Spider_Amazon','REQUEST_HEADERS' : {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en',}}def parse(self, response):pass #1、name = 'amazon' 定義爬蟲名,scrapy會根據該值定位爬蟲程序 所以它必須要有且必須唯一(In Python 2 this must be ASCII only.)#2、allowed_domains = ['www.amazon.cn'] 定義允許爬取的域名,如果OffsiteMiddleware啟動(默認就啟動), 那么不屬于該列表的域名及其子域名都不允許爬取 如果爬取的網址為:https://www.example.com/1.html,那就添加'example.com'到列表.#3、start_urls = ['http://www.amazon.cn/'] 如果沒有指定url,就從該列表中讀取url來生成第一個請求#4、custom_settings 值為一個字典,定義一些配置信息,在運行爬蟲程序時,這些配置會覆蓋項目級別的配置 所以custom_settings必須被定義成一個類屬性,由于settings會在類實例化前被加載#5、settings 通過self.settings['配置項的名字']可以訪問settings.py中的配置,如果自己定義了custom_settings還是以自己的為準#6、logger 日志名默認為spider的名字 self.logger.debug('=============>%s' %self.settings['BOT_NAME'])#5、crawler:了解 該屬性必須被定義到類方法from_crawler中#6、from_crawler(crawler, *args, **kwargs):了解 You probably won’t need to override this directly because the default implementation acts as a proxy to the __init__() method, calling it with the given arguments args and named arguments kwargs.#7、start_requests() 該方法用來發起第一個Requests請求,且必須返回一個可迭代的對象。它在爬蟲程序打開時就被Scrapy調用,Scrapy只調用它一次。 默認從start_urls里取出每個url來生成Request(url, dont_filter=True)#針對參數dont_filter,請看自定義去重規則 如果你想要改變起始爬取的Requests,你就需要覆蓋這個方法,例如你想要起始發送一個POST請求,如下 class MySpider(scrapy.Spider):name = 'myspider'def start_requests(self):return [scrapy.FormRequest("http://www.example.com/login",formdata={'user': 'john', 'pass': 'secret'},callback=self.logged_in)]def logged_in(self, response):# here you would extract links to follow and return Requests for# each of them, with another callbackpass#8、parse(response) 這是默認的回調函數,所有的回調函數必須返回an iterable of Request and/or dicts or Item objects.#9、log(message[, level, component]):了解 Wrapper that sends a log message through the Spider’s logger, kept for backwards compatibility. For more information see Logging from Spiders.#10、closed(reason) 爬蟲程序結束時自動觸發 定制scrapy.spider屬性與方法詳解 去重規則應該多個爬蟲共享的,但凡一個爬蟲爬取了,其他都不要爬了,實現方式如下#方法一: 1、新增類屬性 visited=set() #類屬性2、回調函數parse方法內: def parse(self, response):if response.url in self.visited:return None.......self.visited.add(response.url) #方法一改進:針對url可能過長,所以我們存放url的hash值 def parse(self, response):url=md5(response.request.url)if url in self.visited:return None.......self.visited.add(url) #方法二:Scrapy自帶去重功能 配置文件: DUPEFILTER_CLASS = 'scrapy.dupefilter.RFPDupeFilter' #默認的去重規則幫我們去重,去重規則在內存中 DUPEFILTER_DEBUG = False JOBDIR = "保存范文記錄的日志路徑,如:/root/" # 最終路徑為 /root/requests.seen,去重規則放文件中 scrapy自帶去重規則默認為RFPDupeFilter,只需要我們指定 Request(...,dont_filter=False) ,如果dont_filter=True則告訴Scrapy這個URL不參與去重。#方法三: 我們也可以仿照RFPDupeFilter自定義去重規則,from scrapy.dupefilter import RFPDupeFilter,看源碼,仿照BaseDupeFilter#步驟一:在項目目錄下自定義去重文件dup.py class UrlFilter(object):def __init__(self):self.visited = set() #或者放到數據庫 @classmethoddef from_settings(cls, settings):return cls()def request_seen(self, request):if request.url in self.visited:return Trueself.visited.add(request.url)def open(self): # can return deferredpassdef close(self, reason): # can return a deferredpassdef log(self, request, spider): # log that a request has been filteredpass#步驟二:配置文件settings.py: DUPEFILTER_CLASS = '項目名.dup.UrlFilter'# 源碼分析: from scrapy.core.scheduler import Scheduler 見Scheduler下的enqueue_request方法:self.df.request_seen(request) 去重規則:去除重復的url #例一: import scrapyclass 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):self.logger.info('A response from %s just arrived!', response.url)#例二:一個回調函數返回多個Requests和Items import scrapyclass 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):for h3 in response.xpath('//h3').extract():yield {"title": h3}for url in response.xpath('//a/@href').extract():yield scrapy.Request(url, callback=self.parse)#例三:在start_requests()內直接指定起始爬取的urls,start_urls就沒有用了,import scrapy from myproject.items import MyItemclass MySpider(scrapy.Spider):name = 'example.com'allowed_domains = ['example.com']def start_requests(self):yield scrapy.Request('http://www.example.com/1.html', self.parse)yield scrapy.Request('http://www.example.com/2.html', self.parse)yield scrapy.Request('http://www.example.com/3.html', self.parse)def parse(self, 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) 例子 我們可能需要在命令行為爬蟲程序傳遞參數,比如傳遞初始的url,像這樣 #命令行執行 scrapy crawl myspider -a category=electronics#在__init__方法中可以接收外部傳進來的參數 import scrapyclass MySpider(scrapy.Spider):name = 'myspider'def __init__(self, category=None, *args, **kwargs):super(MySpider, self).__init__(*args, **kwargs)self.start_urls = ['http://www.example.com/categories/%s' % category]#...#注意接收的參數全都是字符串,如果想要結構化的數據,你需要用類似json.loads的方法 參數傳遞?
轉載于:https://www.cnblogs.com/lujiacheng-Python/p/10162540.html
總結
以上是生活随笔為你收集整理的scrapy之spiders的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【家庭药箱系列】布洛芬小史
- 下一篇: SQL server 插入日期处理