網(wǎng)站介紹視頻怎么做百度賬戶安全中心
今天我們先學(xué)習(xí)一下scrapy的入門,Scrapy是一個(gè)快速的高層次的網(wǎng)頁(yè)爬取和網(wǎng)頁(yè)抓取框架,用于爬取網(wǎng)站并從頁(yè)面中提取結(jié)構(gòu)化的數(shù)據(jù)。
1. scrapy的概念和流程
1.1 scrapy的概念
我們先來(lái)了解一下scrapy的概念,什么是scrapy:
Scrapy是一個(gè)Python編寫的開源網(wǎng)絡(luò)爬蟲框架。它是一個(gè)被設(shè)計(jì)用于爬取網(wǎng)絡(luò)數(shù)據(jù)、提取結(jié)構(gòu)性數(shù)據(jù)的框架。而框架就是把之前簡(jiǎn)單的操作抽象成一套系統(tǒng),這樣我們?cè)谑褂每蚣艿臅r(shí)候,它會(huì)自動(dòng)的幫我們完成很多工作,我們只需要完成剩余部分
?Scrapy 使用了Twisted['tw?st?d]異步網(wǎng)絡(luò)框架,可以加快我們的下載速度。
Scrapy文檔地址:http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/overview.html
1.2. scrapy框架的作用
?少量的代碼,就能夠快速的抓取 ,框架是代碼的半成品,提高效率(爬蟲效率和開發(fā)效率)
scrapy框架是一個(gè)用于網(wǎng)絡(luò)爬蟲的快速、高層次的框架,它提供了一套豐富的功能,使得從網(wǎng)站上抓取數(shù)據(jù)變得簡(jiǎn)單和高效。
1. 3. scrapy的工作流程:
上面的流程可以改寫為
?scrapy的流程 (可以理解為是3.2流程的抽象化流程)
以下是完整的對(duì)這個(gè)過(guò)程的解釋:
1. 爬蟲中起始的url構(gòu)造成request對(duì)象-->爬蟲中間件-->引擎-->調(diào)度器
2. 調(diào)度器把request-->引擎-->下載中間件--->下載器
3. 下載器發(fā)送請(qǐng)求,獲取response響應(yīng)---->下載中間件---->引擎--->爬蟲中間件--->爬蟲
4. 爬蟲提取url地址,組裝成request對(duì)象---->爬蟲中間件--->引擎--->調(diào)度器,重復(fù)步驟2
5. 爬蟲提取數(shù)據(jù)--->引擎--->管道處理和保存數(shù)據(jù)
1.3.1初始請(qǐng)求
用戶在Scrapy項(xiàng)目中定義起始URL(通常是在spiders
目錄下的某個(gè)Spider類中)。
這些URL被轉(zhuǎn)換為Request
對(duì)象,這些對(duì)象被發(fā)送到Scrapy引擎。
在發(fā)送到引擎之前,這些Request
對(duì)象會(huì)經(jīng)過(guò)爬蟲中間件(如果有定義的話)進(jìn)行處理。
1.3.2調(diào)度器(Scheduler)?
調(diào)度好的Request
被再次發(fā)送給引擎。
調(diào)度器根據(jù)優(yōu)先級(jí)、重復(fù)過(guò)濾等因素對(duì)Request
進(jìn)行排序和調(diào)度。
引擎將Request
對(duì)象發(fā)送給調(diào)度器。
1.3.3下載中間件(Downloader Middlewares)
引擎將Request
對(duì)象發(fā)送給下載中間件(如果有定義的話)。
下載中間件可以對(duì)Request
對(duì)象進(jìn)行額外的處理,比如添加請(qǐng)求頭、設(shè)置代理等。
處理后的Request
對(duì)象被發(fā)送到下載器(Downloader)。
1.3.4下載器(Downloader):
下載器負(fù)責(zé)發(fā)送HTTP請(qǐng)求到目標(biāo)網(wǎng)站。
下載器接收響應(yīng)(Response
對(duì)象),并將其發(fā)送回引擎。
在返回給引擎之前,響應(yīng)會(huì)經(jīng)過(guò)下載中間件(如果有定義的話),以便進(jìn)行額外的處理,比如處理cookies、重試失敗的請(qǐng)求等
1.3.5爬蟲(Spiders):
- 引擎將
Response
對(duì)象發(fā)送給對(duì)應(yīng)的爬蟲。 - 爬蟲解析
Response
對(duì)象,提取數(shù)據(jù)(通常是使用XPath、CSS選擇器或正則表達(dá)式)。 - 爬蟲還可以提取新的URL,并生成新的
Request
對(duì)象。 - 這些新的
Request
對(duì)象會(huì)經(jīng)過(guò)爬蟲中間件(如果有定義的話)發(fā)送到引擎。
1.3.6重復(fù)步驟2-5:
對(duì)于爬蟲提取的新URL,流程會(huì)重復(fù)步驟2-5,直到?jīng)]有更多的URL需要處理或者滿足某個(gè)停止條件(比如達(dá)到最大請(qǐng)求數(shù)、達(dá)到某個(gè)時(shí)間限制等)。
1.3.7管道(Pipelines):
爬蟲提取的數(shù)據(jù)被發(fā)送到Item Pipeline(如果有定義的話)。
Item Pipeline負(fù)責(zé)處理這些數(shù)據(jù),比如驗(yàn)證數(shù)據(jù)的完整性、清理HTML標(biāo)簽、將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)或文件系統(tǒng)等。
處理后的數(shù)據(jù)最終會(huì)被保存或丟棄,具體取決于Item Pipeline的實(shí)現(xiàn)。
1.3.8注意:
圖中中文是為了方便理解后加上去的
?圖中綠色線條的表示數(shù)據(jù)的傳遞
?注意圖中中間件的位置,決定了其作用
?注意其中引擎的位置,所有的模塊之前相互獨(dú)立,只和引擎進(jìn)行交互
1.4scrapy的三個(gè)內(nèi)置對(duì)象
1.4.1.request請(qǐng)求對(duì)象:
Request
對(duì)象代表一個(gè)HTTP請(qǐng)求,由Scrapy下載器中間件發(fā)送到互聯(lián)網(wǎng)并等待服務(wù)器的響應(yīng)。?
- 它通常包含以下屬性:
url
(字符串):請(qǐng)求的URL。method
(字符串):HTTP請(qǐng)求方法(如"GET"或"POST")。headers
(字典):一個(gè)字典,包含HTTP頭及其值。body
(字節(jié)串):請(qǐng)求體,用于POST或PUT請(qǐng)求。meta
(字典):用于在Scrapy引擎內(nèi)部傳遞信息的字典。cookies
(字典或CookieJar):與請(qǐng)求一起發(fā)送的cookies。- 其他可能用于特定目的的屬性。
1.4.2.response響應(yīng)對(duì)象:
由url body status headers等構(gòu)成
Response
對(duì)象包含服務(wù)器對(duì)Request
的響應(yīng)。
它通常包含以下屬性:
url
(字符串):響應(yīng)的URL(可能與請(qǐng)求的URL不同,例如由于重定向)。status
(整數(shù)):HTTP狀態(tài)碼(如200表示成功)。headers
(字典):包含HTTP響應(yīng)頭的字典。body
(字節(jié)串):響應(yīng)體,即服務(wù)器返回的數(shù)據(jù)。meta
(字典):與產(chǎn)生該響應(yīng)的Request
對(duì)象中的meta
相同。request
(Request對(duì)象):產(chǎn)生此響應(yīng)的Request
對(duì)象。- 其他可能用于特定目的的屬性。
Scrapy還提供了選擇器(Selectors)來(lái)方便地從Response
對(duì)象中提取數(shù)據(jù),如XPath和CSS選擇器。?
1.4.3.item數(shù)據(jù)對(duì)象:
本質(zhì)是個(gè)字典
Item
對(duì)象用于收集爬蟲從網(wǎng)頁(yè)中提取的數(shù)據(jù)。- 它本質(zhì)上是一個(gè)簡(jiǎn)單的Python字典,但提供了額外的功能,如字段驗(yàn)證和清理。
- 你可以通過(guò)定義自己的
Item
類來(lái)指定爬蟲將收集哪些數(shù)據(jù)。 - 例如,如果你正在編寫一個(gè)爬取電商網(wǎng)站信息的爬蟲,你可能會(huì)定義一個(gè)
ProductItem
類,該類包含name
、price
、description
等字段。
在Scrapy中,你通常會(huì)定義一個(gè)或多個(gè)Item
類來(lái)表示你想要從網(wǎng)站提取的數(shù)據(jù)結(jié)構(gòu)。然后,在你的爬蟲代碼中,你可以創(chuàng)建這些Item
類的實(shí)例,并將提取的數(shù)據(jù)填充到這些實(shí)例中。最后,這些Item
實(shí)例將被Scrapy的管道(Pipeline)系統(tǒng)處理,可能包括清洗、驗(yàn)證和存儲(chǔ)到數(shù)據(jù)庫(kù)等操作。
?1.5 scrapy中每個(gè)模塊的具體作用
注意:爬蟲中間件和下載中間件只是運(yùn)行邏輯的位置不同,作用是重復(fù)的:如替換UA等
2. scrapy的入門使用:
2.1 安裝scrapy:
直接cmd安裝:pip/pip3 install scrapy ?
(換源安裝命令:pip install scrapy -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.comn )
安裝依賴包:pip install pypiwin32
? ? ? ? 如果不安裝,以后的項(xiàng)目會(huì)報(bào)錯(cuò)
? ? ? ? window系統(tǒng)需要安裝,Linux,Mac不需要
2.2 scrapy項(xiàng)目開發(fā)流程
2.2.1. 創(chuàng)建項(xiàng)目:
? ????????scrapy startproject mySpider
2.2.2. 生成一個(gè)爬蟲:
? ????????scrapy genspider lianjia lianjia.com
2.2.3. 提取數(shù)據(jù):
????????根據(jù)網(wǎng)站結(jié)構(gòu)在spider中實(shí)現(xiàn)數(shù)據(jù)采集相關(guān)內(nèi)容
2.2.4. 保存數(shù)據(jù):
????????使用pipeline進(jìn)行數(shù)據(jù)后續(xù)處理和保存
2.3. 創(chuàng)建項(xiàng)目:
通過(guò)命令將scrapy項(xiàng)目的的文件生成出來(lái),后續(xù)步驟都是在項(xiàng)目文件中進(jìn)行相關(guān)操作,下面以抓取鏈家來(lái)學(xué)習(xí)scrapy的入門使用
創(chuàng)建scrapy項(xiàng)目的命令:
scrapy startproject <項(xiàng)目名字>
示例:
????????scrapy startproject myspider
2.4. 創(chuàng)建爬蟲
通過(guò)命令創(chuàng)建出爬蟲文件,爬蟲文件為主要的代碼文件,通常一個(gè)網(wǎng)站的爬取動(dòng)作都會(huì)在爬蟲文件中進(jìn)行編寫。
命令:
????????**在項(xiàng)目路徑下執(zhí)行**:<br/>
????????scrapy genspider <爬蟲名字> <允許爬取的域名>
爬蟲名字: 作為爬蟲運(yùn)行時(shí)的參數(shù)<br/>
允許爬取的域名:
為對(duì)于爬蟲設(shè)置的爬取范圍,設(shè)置之后用于過(guò)濾要爬取的url,如果爬取的url與允許的域不通則被過(guò)濾掉。
示例:
cd myspider ? ? ? ***這一步是進(jìn)入當(dāng)前項(xiàng)目路徑***
scrapy genspider lianjia lianjia.com ? ? ? ?***再創(chuàng)建爬蟲文件***
2.4.1,scrapy.cfg
詳細(xì)項(xiàng)目配置文件, 不需要做改動(dòng)
2.4.2,items.py ?定義數(shù)據(jù)存儲(chǔ)模型
# Define here the models for your scraped items# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapy# 實(shí)際是一個(gè)模板類 主要是用來(lái)定義數(shù)據(jù)存儲(chǔ)模型
# 通過(guò)這個(gè)類實(shí)例化 數(shù)據(jù)實(shí)際存到實(shí)例(對(duì)象)中
class MyspiderItem(scrapy.Item):# 實(shí)際是一個(gè)模板類(數(shù)據(jù)建模) 事先定義好你要爬取的字段name = scrapy.Field() # 租房標(biāo)題content = scrapy.Field() # 詳情信息price = scrapy.Field() # 價(jià)格link = scrapy.Field() # 詳情鏈接
2.4.3,middlewares.py ? 用于編寫中間件(下載中間件+爬蟲中間件) -- 無(wú)特殊需求,一般不需要編寫
# Define here the models for your spider middleware
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/spider-middleware.htmlfrom scrapy import signals# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapterclass MyspiderSpiderMiddleware:# Not all methods need to be defined. If a method is not defined,# scrapy acts as if the spider middleware does not modify the# passed objects.@classmethoddef from_crawler(cls, crawler):# This method is used by Scrapy to create your spiders.s = cls()crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)return sdef process_spider_input(self, response, spider):# Called for each response that goes through the spider# middleware and into the spider.# Should return None or raise an exception.return Nonedef process_spider_output(self, response, result, spider):# Called with the results returned from the Spider, after# it has processed the response.# Must return an iterable of Request, or item objects.for i in result:yield idef process_spider_exception(self, response, exception, spider):# Called when a spider or process_spider_input() method# (from other spider middleware) raises an exception.# Should return either None or an iterable of Request or item objects.passdef process_start_requests(self, start_requests, spider):# Called with the start requests of the spider, and works# similarly to the process_spider_output() method, except# that it doesn’t have a response associated.# Must return only requests (not items).for r in start_requests:yield rdef spider_opened(self, spider):spider.logger.info('Spider opened: %s' % spider.name)class MyspiderDownloaderMiddleware:# Not all methods need to be defined. If a method is not defined,# scrapy acts as if the downloader middleware does not modify the# passed objects.@classmethoddef from_crawler(cls, crawler):# This method is used by Scrapy to create your spiders.s = cls()crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)return sdef process_request(self, request, spider):# Called for each request that goes through the downloader# middleware.# Must either:# - return None: continue processing this request# - or return a Response object# - or return a Request object# - or raise IgnoreRequest: process_exception() methods of# installed downloader middleware will be calledreturn Nonedef process_response(self, request, response, spider):# Called with the response returned from the downloader.# Must either;# - return a Response object# - return a Request object# - or raise IgnoreRequestreturn responsedef process_exception(self, request, exception, spider):# Called when a download handler or a process_request()# (from other downloader middleware) raises an exception.# Must either:# - return None: continue processing this exception# - return a Response object: stops process_exception() chain# - return a Request object: stops process_exception() chainpassdef spider_opened(self, spider):spider.logger.info('Spider opened: %s' % spider.name)
2.4.4,lianjia.py (爬蟲文件,文件名稱自己定義) ?[后面再來(lái)完善該爬蟲模塊]
import scrapyclass LianjiaSpider(scrapy.Spider):# 爬蟲名字name = 'lianjia'# 限定爬取的域名范圍allowed_domains = ['cs.lianjia.com']# 起始請(qǐng)求的URLstart_urls = ['https://cs.lianjia.com/zufang/']# 該方法會(huì)接受下載中間件傳過(guò)來(lái)的response,并對(duì)其進(jìn)行解析def parse(self, response):pass
2.4.5,pipelines.py ? 管道 -- 主要用于編寫數(shù)據(jù)處理步驟 (數(shù)據(jù)的清洗+保存)
# Define your item pipelines here# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html# useful for handling different item types with a single interface
from itemadapter import ItemAdapterclass MyspiderPipeline:def process_item(self, itemder):return item
2.4.6,settings.py ? 詳細(xì)的配置信息(設(shè)置文件UA ?并啟動(dòng)管道)
# Scrapy settings for mySpider project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
# https://docs.scrapy.org/en/latest/topics/settings.html
# https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
# https://docs.scrapy.org/en/latest/topics/spider-middleware.htmlBOT_NAME = 'mySpider'SPIDER_MODULES = ['mySpider.spiders']
NEWSPIDER_MODULE = 'mySpider.spiders'# Crawl responsibly by identifying yourself (and your website) on the user-agent
# 需要手動(dòng)修改成自己瀏覽器的UA
USER_AGENT = 'mySpider (+http://www.yourdomain.com)'# Obey robots.txt rules
ROBOTSTXT_OBEY = False # 需要手動(dòng)修改為False# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16# Disable cookies (enabled by default)
#COOKIES_ENABLED = False# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False# Override the default request headers:
# 可以寫入一些爬蟲所需要的身份信息
#DEFAULT_REQUEST_HEADERS = {
# 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
# 'Accept-Language': 'en',
#}# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
# SPIDER_MIDDLEWARES = {
# 'mySpider.middlewares.MyspiderSpiderMiddleware': 543,
# }# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
# 'mySpider.middlewares.MyspiderDownloaderMiddleware': 543,
#}# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html#EXTENSIONS = {
# 'scrapy.extensions.telnet.TelnetConsole': None,
#}# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# 開啟管道類才能寫入數(shù)據(jù)
ITEM_PIPELINES = {'mySpider.pipelines.MyspiderPipeline': 300,
}# Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#AUTOTHROTTLE_ENABLED = True
# The initial download delay
#AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
#AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
2.5. 完善爬蟲
在上一步生成出來(lái)的爬蟲文件中編寫指定網(wǎng)站的數(shù)據(jù)采集操作,實(shí)現(xiàn)數(shù)據(jù)提取
2.5.1 在/myspider/myspider/spiders/itcast.py中修改內(nèi)容如下:
import scrapy
from mySpider.items import MyspiderItemclass LianjiaSpider(scrapy.Spider):# 爬蟲名字name = 'lianjia'# 限定爬取的域名范圍allowed_domains = ['cs.lianjia.com']# 起始請(qǐng)求的URLstart_urls = ['https://cs.lianjia.com/zufang/']# 該方法會(huì)接受下載中間件傳過(guò)來(lái)的response,并對(duì)其進(jìn)行解析def parse(self, response):# print("響應(yīng)對(duì)象:",response) # response是一個(gè)響應(yīng)對(duì)象# html_data = response.body # 獲取網(wǎng)頁(yè)源碼# print("源碼信息:", html_data)# # 將獲取回來(lái)的網(wǎng)頁(yè)源碼保存為本地html文件,方便做分析# with open('lj.html','wb')as f:# f.write(html_data)# 正式解析想要的數(shù)據(jù)# 會(huì)返回一個(gè)為列表的Selector選擇器對(duì)象# 將列表遍歷成字符串再通過(guò).extract()取選擇器里的所有值,.extract_first()取出選擇器里的第一個(gè)值name = response.xpath('//div[@class="content__list--item--main"]//p[@class="content__list--item--title"]/a/text()').extract()price = response.xpath('//div[@class="content__list--item--main"]//em/text()').extract()link = response.xpath('//div[@class="content__list--item--main"]//a[@class="twoline"]/@href').extract()for names, prices, links in zip(name, price, link):# 創(chuàng)建一個(gè)數(shù)據(jù)字典# item = {}# 調(diào)用items模板類item = MyspiderItem() #實(shí)例化之后可以直接使用 目前是一個(gè)空字典# 給實(shí)例之后的空字典組建數(shù)據(jù) 要注意得與items文件中定義的變量一致item["name"] = names.strip()item["price"] = pricesitem["link"] = "https://cs.lianjia.com/" + links# print(names.strip())# print(prices)# print("https://cs.lianjia.com/"+links)# print('=='*10)# print(item)# 將組建好的dict形式數(shù)據(jù)通過(guò)yield返回給引擎 再交給管道文件Pipelineyield item
注意:
- scrapy.Spider爬蟲類中必須有名為parse的解析
- 如果網(wǎng)站結(jié)構(gòu)層次比較復(fù)雜,也可以自定義其他解析函數(shù)
- 在解析函數(shù)中提取的url地址如果要發(fā)送請(qǐng)求,則必須屬于allowed_domains范圍內(nèi),但是start_urls中的url地址不受這個(gè)限制,我們會(huì)在后續(xù)的課程中學(xué)習(xí)如何在解析函數(shù)中構(gòu)造發(fā)送請(qǐng)求
- 啟動(dòng)爬蟲的時(shí)候注意啟動(dòng)的位置,是在項(xiàng)目路徑下啟動(dòng)
- parse()函數(shù)中使用yield返回?cái)?shù)據(jù),
注意:解析函數(shù)中的yield能夠傳遞的對(duì)象只能是:BaseItem, Request, dict, None
2.5.2 定位元素以及提取數(shù)據(jù)、屬性值的方法
解析并獲取scrapy爬蟲中的數(shù)據(jù): 利用xpath規(guī)則字符串進(jìn)行定位和提取
1. response.xpath方法的返回結(jié)果是一個(gè)類似list的類型,其中包含的是selector對(duì)象,操作和列表一樣,但是有一些額外的方法
2. 額外方法extract():返回一個(gè)包含有字符串的列表
3. 額外方法extract_first():返回列表中的第一個(gè)字符串,列表為空沒有返回None
2.6 保存數(shù)據(jù)
?利用管道pipeline來(lái)處理(保存)數(shù)據(jù)
2. 6.1 在pipelines.py文件中定義對(duì)數(shù)據(jù)的操作
1. 定義一個(gè)管道類
2. 重寫管道類的process_item方法
3. process_item方法處理完item之后必須返回給引擎
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html# useful for handling different item types with a single interface
import jsonfrom itemadapter import ItemAdapterclass MyspiderPipeline:def __init__(self):self.file = open('lianjia.json','w')# 爬蟲文件中提取數(shù)據(jù)的方法每yield一次item,就會(huì)運(yùn)行一次# 該方法為固定名稱函數(shù)def process_item(self, item, spider):# 參數(shù)item默認(rèn)是一個(gè) <class 'mySpider.items.MyspiderItem'>類信息,需要處理成字典dict_data = dict(item)print(type(item), type(dict_data))# 將返回的字典數(shù)據(jù)轉(zhuǎn)為JSON數(shù)據(jù)json_data = json.dumps(dict_data,ensure_ascii=False)+',\n'# 寫入JSON數(shù)據(jù)self.file.write(json_data)# 參數(shù)item:是爬蟲文件中yield的返回的數(shù)據(jù)對(duì)象(引擎會(huì)把這個(gè)交給管道中的這個(gè)item參數(shù))print("建模之后的返回值:",item,)# 默認(rèn)使用完管道之后將數(shù)據(jù)又返回給引擎return itemdef __del__(self):self.file.close()
2. 6.2 在settings.py配置啟用管道
# ? 設(shè)置目錄文件 ? ? ? ? ? ? ? 該值的大小決定管道執(zhí)行的順序,值越小優(yōu)先級(jí)越高(該值最好 不要大于1000) ?ITEM_PIPELINES = {'mySpider.pipelines.MyspiderPipeline': 300,}
以上配置項(xiàng)中鍵為使用的管道類,管道類使用.進(jìn)行分割,第一個(gè)為項(xiàng)目目錄,第二個(gè)為文件,第三個(gè)為定義的管道類。
配置項(xiàng)中值為管道的使用順序,設(shè)置的數(shù)值約小越優(yōu)先執(zhí)行,該值一般設(shè)置為1000以內(nèi)。
2.7. 運(yùn)行scrapy
命令:在項(xiàng)目目錄下執(zhí)行scrapy crawl <爬蟲名字>
示例:scrapy crawl 爬蟲名字 --nolog 忽略日志信息
2.7.1 ?也可爬蟲項(xiàng)目中執(zhí)行命令
每次我們寫完代碼進(jìn)行測(cè)試的時(shí)候,都要去安裝目錄執(zhí)行,所以為了方便,我們要寫一個(gè)再爬蟲項(xiàng)目根目錄中創(chuàng)建.py結(jié)尾的文件,執(zhí)行以下指令:
from scrapy import cmdline
cmdline.execute(['scrapy','crawl','lianjia'])
2. 8,Scrapy Shell的使用
我們想要爬蟲中使用xpath,BS4,正則,css選擇器等來(lái)提取想要的數(shù)據(jù)時(shí),由于Scrapy是一個(gè)重量級(jí)框架,每次運(yùn)行起來(lái)都要等待一段時(shí)間,因此要去驗(yàn)證我們書寫的規(guī)則是否正確,是一個(gè)比較麻煩的事情,因此Scrapy提供了一個(gè)shell,用起來(lái)方便測(cè)試規(guī)則
打開Scrapy Shell
打開cmd終端,進(jìn)入到Scrapy項(xiàng)目所在目錄,進(jìn)入到Scrapy框架所在的環(huán)境中,輸入命令:
?scrapy shell url ,就會(huì)進(jìn)入到scrapy的shell環(huán)境中,在這個(gè)環(huán)境中,你可以跟在爬蟲的parse方法中一樣使用了
例如:
? ?cd mySpider ?進(jìn)入項(xiàng)目路徑
? ?scrapy shell https://cs.lianjia.com/zufang/ ?#想要測(cè)試的url
? ?link = response.xpath('//div[@class="content__list--item--main"]//a[@class="twoline"]/@href').extract()
2. 9. 翻頁(yè)請(qǐng)求的思路
對(duì)于要提取如下圖中所有頁(yè)面上的數(shù)據(jù)該怎么辦?

回顧requests模塊是如何實(shí)現(xiàn)翻頁(yè)請(qǐng)求的:
1. 找到下一頁(yè)的URL地址
2. 調(diào)用requests.get(url)
scrapy實(shí)現(xiàn)翻頁(yè)的思路:
(scrapy并無(wú)單獨(dú)的url這個(gè)概念,scrapy中都是需要將url打包成一個(gè)請(qǐng)求對(duì)象)
1. 找到下一頁(yè)的url地址
2. 把url地址構(gòu)造成請(qǐng)求對(duì)象,傳遞給引擎
2.10.如何構(gòu)造Request對(duì)象,并發(fā)送請(qǐng)求
2.10.1 實(shí)現(xiàn)方法
1. 確定url地址
2. 構(gòu)造請(qǐng)求,scrapy.Request(url,callback)
? ?- callback:指定響應(yīng)體解析的函數(shù)名稱,表示該請(qǐng)求返回的響應(yīng)使用哪一個(gè)函數(shù)進(jìn)行解析(callback不賦值的話默認(rèn)是給parse方法解析)
3. 把請(qǐng)求交給引擎:yield scrapy.Request(url,callback)
2.10.2 鏈家爬蟲
通過(guò)爬取鏈家頁(yè)面信息,學(xué)習(xí)如何實(shí)現(xiàn)翻頁(yè)請(qǐng)求
?地址:https://xy.lianjia.com/zufang/pg1/
思路分析:
1. 獲取首頁(yè)的響應(yīng)數(shù)據(jù)(因?yàn)槔锩嬗形覀兿胍姆?yè)鏈接)
2. 尋找下一頁(yè)的地址,進(jìn)行翻頁(yè),獲取數(shù)據(jù)
2.10.3 代碼實(shí)現(xiàn)
在爬蟲文件的parse方法中:
# 開始構(gòu)造翻頁(yè)# 1,提取下一頁(yè)urlall_url = response.xpath('//ul[@style="display:hidden"]//li/a/@href').extract()print(all_url)for part_url in all_url:# 2,判斷條件if '/zufang/' in part_url:next_url = response.urljoin(part_url)print("下一頁(yè)參數(shù)信息:", part_url)print("下一頁(yè)鏈接:", next_url)# 構(gòu)建請(qǐng)求對(duì)象 并且返回給引擎yield scrapy.Request(url=next_url,callback=self.parse)
?
3.小結(jié)
1. scrapy的安裝:pip install scrapy
2. 創(chuàng)建scrapy的項(xiàng)目: scrapy startproject myspider
3. 創(chuàng)建scrapy爬蟲:在項(xiàng)目目錄下執(zhí)行 scrapy genspider lianjia ?lianjia.com
4. 運(yùn)行scrapy爬蟲:在項(xiàng)目目錄下執(zhí)行scrapy crawl 爬蟲名字 ? ? 【scrapy crawl 爬蟲名字 --nolog 忽略日志信息】
5. 解析并獲取scrapy爬蟲中的數(shù)據(jù):
? ?1. response.xpath方法的返回結(jié)果是一個(gè)類似list的類型,其中包含的是selector對(duì)象,操作和列表一樣,但是有一些額外的方法
? ?2. extract() 返回一個(gè)包含有字符串的列表
? ?3. extract_first() 返回列表中的第一個(gè)字符串,列表為空沒有返回None
6. scrapy管道的基本使用:
? ?1. 完善pipelines.py中的process_item方法
? ?2. 在settings.py中設(shè)置開啟pipeline
7. response響應(yīng)對(duì)象的常用屬性
? ?1. response.url:獲取當(dāng)前響應(yīng)的url地址
? ?2. response.request.url:獲取當(dāng)前響應(yīng)對(duì)應(yīng)的請(qǐng)求的url地址
? ?3. response.headers:獲取響應(yīng)頭
? ?4. response.urljoin(url) :用于構(gòu)造絕對(duì)url, 當(dāng)傳入的url參數(shù)是一個(gè)相對(duì)地址時(shí), 根據(jù)response.url計(jì)算出相應(yīng)的絕對(duì)url.
? ?5. response.body:獲取響應(yīng)體,也就是html代碼,byte類型
? ?6. response.text: 獲取響應(yīng)體,str類型
? ?7. response.status:獲取響應(yīng)狀態(tài)碼
8. request請(qǐng)求對(duì)象的常用屬性
? ?1. request.url(必選):請(qǐng)求頁(yè)面的url地址,bytes或str類型。
? ?2. request.callback:頁(yè)面解析函數(shù),Callback類型,Request請(qǐng)求對(duì)象的頁(yè)面下載完成后,由該參數(shù)指定的頁(yè)面解析函數(shù)解析頁(yè)面,如果未傳遞該參數(shù),默認(rèn)調(diào)用Spider的parse方法。
? ?3. request.method:HTTP請(qǐng)求的方法,默認(rèn)為‘GET’。
? ?4. request.headers:HTTP請(qǐng)求的頭部字典,dict 類型。
? ?5. request.meta:Request 的元數(shù)據(jù)字典,dict 類型,用于給框架中其他組件傳遞信息,比如中間件 Item Pipeline。其他組件可以使用Request 對(duì)象的 meta 屬性訪問(wèn)該元數(shù)據(jù)字典 (request.meta), 也用于給響應(yīng)處理函數(shù)傳遞信息。
? ?6. request.encoding:url 和 body 參數(shù)的編碼默認(rèn)為'utf-8'。如果傳入的url或body參數(shù)是str 類型,就使用該參數(shù)進(jìn)行編碼。
? ?7. request.dont_filter:默認(rèn)情況下(dont_filter=False),對(duì)同一個(gè)url地址多次提交下載請(qǐng)求,后面的請(qǐng)求會(huì)被去重過(guò)濾器過(guò)濾(避免重復(fù)下載)。如果將該參數(shù)置為True,可以使請(qǐng)求避免被過(guò)濾,強(qiáng)制下載。例如:在多次爬取一個(gè)內(nèi)容隨時(shí)間而變化的頁(yè)面時(shí)(每次使用相同的url),可以將該參數(shù)設(shè)置為True。
結(jié)語(yǔ):
今天給大家分享的是關(guān)于scrapy的初級(jí)入門學(xué)習(xí),由于這篇的篇幅比較長(zhǎng)所有我更新的比較慢,希望大家見諒.這些都是我自己的學(xué)習(xí)過(guò)程中的一些筆記歡迎大家的指正和歡迎大家在評(píng)論區(qū)和諧討論。