scrapy框架

scrapy框架
Scrapy是用純Python實(shí)現(xiàn)一個(gè)為了爬取網(wǎng)站數(shù)據(jù)刀荒、提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架,用途非常廣泛。

scrapy架構(gòu)圖

scrapy各部分簡介:

Scrapy Engine(引擎): 負(fù)責(zé)信號和數(shù)據(jù)的傳遞,起協(xié)調(diào)作用.(框架幫我們實(shí)現(xiàn)了)

Scheduler(調(diào)度器): 會(huì)將Request請求任務(wù),存儲(chǔ)在任務(wù)隊(duì)列中曼追,引擎會(huì)從任務(wù)隊(duì)列中提取任務(wù)交給下載器 (框架幫我們實(shí)現(xiàn)了)

只有當(dāng)調(diào)度器中不存在任何request了汉规,整個(gè)程序才會(huì)停止礼殊,(也就是說驹吮,對于下載失敗的URL,Scrapy也會(huì)重新下載晶伦。)

Downloader(下載器):接收引擎?zhèn)鬟f過來的請求碟狞,發(fā)起請求,獲取響應(yīng)婚陪,最終將響應(yīng)結(jié)果交給spider爬蟲文件(框架幫我們實(shí)現(xiàn)了)

Spider(爬蟲):根據(jù)起始url發(fā)起請求族沃,解析響應(yīng)結(jié)果,第一獲取目標(biāo)數(shù)據(jù)泌参,第二提取新的url  〈嘌汀(手動(dòng)實(shí)現(xiàn))

Item Pipeline(管道):將spider爬蟲文件yeild的item數(shù)據(jù),做過濾和持久化 」烈弧(手動(dòng)實(shí)現(xiàn)的)

Downloader Middlewares(下載中間件):自定義下載組件(請求任務(wù)和響應(yīng)結(jié)果都會(huì)經(jīng)過下載中間件)代理中間件盖溺,cookies中間件,Uaer-Agent中間件铣缠,selenium中間件..『嬷觥(特殊需求要手動(dòng)實(shí)現(xiàn))

Spider Middlewares(Spider中間件):可以自定義request請求和過濾Response響應(yīng)  (特殊需求要手動(dòng)實(shí)現(xiàn))

安裝

sudo pip3 install scrapy

新建項(xiàng)目

scrapy startproject 爬蟲項(xiàng)目名稱

然后cd到spider文件夾下

新建爬蟲文件

crapy genspider 爬蟲文件名稱 域名:制作爬蟲開始爬取網(wǎng)頁

在這個(gè)時(shí)候我們項(xiàng)目的目錄結(jié)構(gòu)應(yīng)該會(huì)是這樣的

一個(gè)項(xiàng)目有5個(gè)文件我們一般情況下會(huì)進(jìn)行修改

1.pipeline.py

做數(shù)據(jù)的過濾和持久化

可以在這里做數(shù)據(jù)持久化, 如果有多個(gè)管道文件,并且有優(yōu)先級順序一定要記住return item,否則下一個(gè)管道無法接受item

它還要兩個(gè)可選方法

def open_spider(self,spider):

? ? ? ? 可選方法蝗蛙,在爬蟲開始執(zhí)行的時(shí)候調(diào)用一次

? ? ? ? print(spider.name,'爬蟲開啟')

? ? def close_spider(self,spider):

? ? ? ? 可選方法,在爬蟲結(jié)束的時(shí)候調(diào)用一次

? ? ? ? self.file.close()

? ? ? ? print(spider.name,'爬蟲結(jié)束')

2.item.py

根據(jù)目標(biāo)網(wǎng)站蝇庭,定義要提取的目標(biāo)字段

3.spiders.py

spiders文件夾下存放的是爬蟲文件

name

? ? 定義spider名字的字符串。

allowed_domains

? ? 包含了spider允許爬取的域名(domain)的列表歼郭,可選。

start_urls

? ? 初始URL元組/列表辐棒。當(dāng)沒有制定特定的URL時(shí)病曾,spider將從該列表中開始進(jìn)行爬取。

start_requests(self)

? ? 該方法必須返回一個(gè)可迭代對象(iterable)漾根。該對象包含了spider用于爬忍┩俊(默認(rèn)實(shí)現(xiàn)是使用 start_urls 的url)的第一個(gè)Request。

? ? 當(dāng)spider啟動(dòng)爬取并且未指定start_urls時(shí)辐怕,該方法被調(diào)用逼蒙。

parse(self, response)

? ? 當(dāng)請求url返回網(wǎng)頁沒有指定回調(diào)函數(shù)時(shí),默認(rèn)的Request對象回調(diào)函數(shù)寄疏。

yield 的作用就是把一個(gè)函數(shù)變成一個(gè) generator(生成器)是牢,帶有 yield 的函數(shù)不再是一個(gè)普通函數(shù),Python 解釋器會(huì)將其視為一個(gè) generator

4.settings.py

設(shè)置文件,可以在里面做User-Agent陕截,Headers驳棱,激活管道文件等等

BOT_NAME

(也是項(xiàng)目名稱)。使用 startproject 命令創(chuàng)建項(xiàng)目時(shí)會(huì)被自動(dòng)賦值农曲。

SPIDER_MODULES = ['ziruproject.spiders'] NEWSPIDER_MODULE = 'ziruproject.spiders'

爬蟲的文件路徑

USER_AGENT

用戶代理社搅,一般設(shè)置這個(gè)參數(shù)用來偽裝瀏覽器請求

ROBOTSTXT_OBEY

是否遵守ROBOT協(xié)議,為False時(shí),表示不遵守形葬,

為True時(shí)表示遵守(默認(rèn)為True)

COOKIES_ENABLED

是否要攜帶cookies合呐,一般情況下,不是必須要攜帶

cookies的請求笙以,我們將這個(gè)參數(shù)設(shè)置為False淌实,(默認(rèn)為True)

DEFAULT_REQUEST_HEADERS

默認(rèn): 如下

{

'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

'Accept-Language': 'en',

}

用于Scrapy HTTP請求的默認(rèn)標(biāo)頭

ITEM_PIPELINES

設(shè)置并激活管道文件,為了存儲(chǔ)數(shù)據(jù)使用源织,

后面的數(shù)字表示優(yōu)先級翩伪,數(shù)字越小,優(yōu)先級越高

關(guān)于日志信息的設(shè)置

LOG_ENABLED

默認(rèn): True

是否啟用logging谈息。

LOG_FILE

默認(rèn): None

logging輸出的文件名缘屹。如果為None,則使用標(biāo)準(zhǔn)錯(cuò)誤輸出(standard error)侠仇。

Logging使用

Scrapy提供了log功能轻姿,可以通過 logging 模塊使用。

可以修改配置文件settings.py逻炊,任意位置添加下面兩行互亮,效果會(huì)清爽很多。

LOG_FILE = "TencentSpider.log"

LOG_LEVEL = "INFO"

5.middleware.py

下載中間件和爬蟲中間件

middleware的使用主要是為了自定義一些第三方組件余素,是爬蟲和反爬的重要過程

主要有四種:

1.隨機(jī)User-Agent

2.自定義隨機(jī)cookies

3.enium結(jié)合使用

4.自定義隨機(jī)ip池

除了一般的scrapy框架之外還有通用爬蟲

通用爬蟲和一般爬蟲的區(qū)別主要是多了一個(gè)Rule的規(guī)則

他的主要參數(shù)是:

LinkExtractor中有:

allow:一般設(shè)置一個(gè)正則表達(dá)式豹休,符合該正則表達(dá)式的連接,提取該url(常用)

deny:同樣是跟一個(gè)正則表達(dá)式桨吊,符合該正則表達(dá)式的連接威根,不提取該url

(優(yōu)先級比allow要高)

?allowed_domains:提取的連接,必須在allowed_domains設(shè)置的域下

? deny_domains: 提取鏈接時(shí)视乐,一定不能提取deny_domains設(shè)置的域下

restrict_xpaths:當(dāng)提取鏈接的時(shí)候洛搀,我們可以使用xpath語法定位到某些標(biāo)簽,提取標(biāo)簽下佑淀,

?符合規(guī)則的鏈接×裘馈(常用)

tags:可以指定要提取哪些標(biāo)簽

?attrs:可以指定要提取標(biāo)簽的哪些屬性

?restrict_css:當(dāng)提取鏈接的時(shí)候,我們可以使用css語法定位到某些標(biāo)簽伸刃,提取標(biāo)簽下谎砾,

?符合規(guī)則的鏈接 (常用)

還有:

callback='回調(diào)函數(shù)名稱',

?follow=True | False,? # 表示是否要跟進(jìn)

爬蟲的步驟

step1:

分析目標(biāo)網(wǎng)站,根據(jù)要提取的目標(biāo)數(shù)據(jù)捧颅,在items.py中自定義字段

step2:

? ? 在爬蟲文件中:(1)首先設(shè)置目標(biāo)url

? ? ? ? ? ? ? ? ????????????????(2) 解析請求成功的響應(yīng)結(jié)果,提取目標(biāo)數(shù)據(jù)棺榔,賦值給item,提取新的url,繼續(xù)發(fā)起請求

step3:

? ? (1) 在設(shè)置文件中激活管道

? ? (2) 在管道文件中做數(shù)據(jù)的過濾和持久化

注意:

1.進(jìn)入項(xiàng)目一定要先設(shè)置虛擬環(huán)境

2.首先更改settings的幾個(gè)配置

? ? (1).ROBOTSTXT_OBEY

是否遵守ROBOT協(xié)議隘道,為False時(shí)症歇,表示不遵守郎笆,

為True時(shí)表示遵守(默認(rèn)為True)

(2).COOKIES_ENABLED

是否要攜帶cookies,一般情況下忘晤,不是必須要攜帶

cookies的請求宛蚓,我們將這個(gè)參數(shù)設(shè)置為False,(默認(rèn)為True)

(3).DEFAULT_REQUEST_HEADERS

此設(shè)置是設(shè)置一個(gè)全局的請求頭

默認(rèn): 如下

{

'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

'Accept-Language': 'en',

}

(4).DOWNLOAD_DELAY =1(防止訪問過于頻繁)

表示延時(shí)下載设塔,一般情況下設(shè)為1或2

通用爬蟲:為了全站爬取

通用爬蟲創(chuàng)建項(xiàng)目

scrapy genspider -t crawl 爬蟲名稱 域

通用爬蟲與普通爬蟲的區(qū)別就在于多了一個(gè)rules規(guī)則

rules 規(guī)則屬性的參數(shù):是一個(gè)元組,可以放多個(gè)Rule對象

創(chuàng)建Rule:

LinkExtractor:設(shè)置提取規(guī)則

(allow,deny,allow_domea..,deny_domea..,restrict_xpath,restrict_css)

callback:設(shè)置回調(diào)函數(shù)

follwer:是否跟進(jìn)

process_links:設(shè)置一個(gè)函數(shù),根據(jù)正則規(guī)則獲取的url,可以在回調(diào)函數(shù)中獲取到

processs_request:設(shè)置一個(gè)函數(shù),可以在這個(gè)回調(diào)方法中攔截所有根據(jù)正則規(guī)則提取到的url構(gòu)建的Request對象

注意:

1.設(shè)置回調(diào)的時(shí)候一定不能重寫parse方法

2.要獲取起始url的響應(yīng)結(jié)果 ,必須重寫parse_start_url

3.在設(shè)置Rule對象的時(shí)候,如果沒有callback回調(diào)函數(shù),默認(rèn)表示跟進(jìn)

什么情況下會(huì)用到通用爬蟲???

當(dāng)我們提取數(shù)據(jù)的目標(biāo)網(wǎng)站的網(wǎng)址很有規(guī)律,并且模塊很清晰,我么就可以使用通用爬蟲class

數(shù)據(jù)持久化之圖片下載

在 ImagesPipeline 類中實(shí)現(xiàn)凄吏,提供了一個(gè)方便并具有額外特性的方法,來下載并本地存儲(chǔ)圖片

首先在setttings里設(shè)置一個(gè)圖片下載路徑

然后在自定義的圖片下載管道里獲取到這個(gè)圖片路徑

第一種:正常的發(fā)起請求 闰蛔,獲取圖片的二進(jìn)制文件痕钢,保存

第二種:自定義圖片管道,繼承自ImagePipline

? ? 重寫兩個(gè)方法:

? ? ? ? def get_media_request(self,item,spider):

? ? ? ? ? ? 獲取圖片地址序六,發(fā)起請求

? ? ? ? def item_completed(self,results,spider,item,....):

? ? ? ? ? ? 在results結(jié)果中根據(jù)圖片下載狀態(tài)任连,獲取圖片本地存儲(chǔ)的路徑,

? ? ? ? ? ? 將獲取的路徑賦值給item,然后將item返回給其他管道

# 數(shù)據(jù)持久化:(切記激活管道)

? ? 1.可以自定義數(shù)據(jù)管道

? ? ? ? def __init__(self,xxx,xxxxx,xxxxx):

? ? ? ? ? ? # 可以設(shè)置一些參數(shù)例诀,(比如随抠,創(chuàng)健數(shù)據(jù)庫鏈接,打開文件等等

? ? ? ? @classmethod

? ? ? ? def from_crawler(cls,crawler):

? ? ? ? ? ? crawler:包含了爬蟲的一些核心組件繁涂,可以獲取settings中的一些參數(shù)

? ? ? ? ? ? return cls(xxx,xxxx,xxxx)

? ? ? ? def open_spider(self,spider):

? ? ? ? ? ? # 可選方法拱她,在爬蟲個(gè)開啟的時(shí)候會(huì)調(diào)用

? ? ? ? def process_item(self,item,spider):

? ? ? ? ? ? # 所有的item都會(huì)經(jīng)過這個(gè)方法

? ? ? ? ? ? # 在這里做數(shù)據(jù)持久化(pymongo,pymysql)

? ? ? ? ? ? # 方法一:

? ? ? ? ? ? if isinstance(item,類名)

? ? ? ? ? ? ? ? 做數(shù)據(jù)插入操作

? ? ? ? ? ? elif isinstance(item,類名)

? ? ? ? ? ? ? ? 做數(shù)據(jù)插入操作

? ? ? ? ? ? 方法二:

? ? ? ? ? ? ? ? 1.在item對應(yīng)的類中,我們定義一個(gè)方法扔罪,返回sql語句和要插入的數(shù)據(jù)

? ? ? ? ? ? ? ? 2.使用item調(diào)用這個(gè)方法秉沼,得到sql語句和要插入的數(shù)據(jù)

? ? ? ? ? ? ? ? 3.執(zhí)行插入操作

? ? ? ? ? ? return item(如果要將item,傳遞給下一個(gè)管道,必須要return)

數(shù)據(jù)持久化之mongodb

首先在settings設(shè)置數(shù)據(jù)庫配置文件

MONGDDBHOST = '127.0.0.1'

MONGODBPORT = 27017

MONGODB_DB = 'dbname'

import pymongo

class QunaPipeline(object):

? ? def __init__(self,MONGODBHOST,MONGODBPORT,MONGODB_DB):


? ? ? ? self.client = pymongo.MongoClient(MONGODBHOST,MONGODBPORT)

? ? ? ? self.db = self.client[MONGODB_DB]

? ? @classmethod

? ? def from_settings(cls,settings):

? ? ? ? MONGODBHOST = settings['MONGODBHOST']

? ? ? ? MONGODBPORT = settings['MONGODBPORT']

? ? ? ? MONGODB_DB = settings['MONGODB_DB']

? ? ? ? return cls(MONGODBHOST,MONGODBPORT,MONGODB_DB)

? ? def process_item(self, item, spider):

? ? ? ? self.db[item.get_db_col()].insert(dict(item))

? ? ? ? return item

數(shù)據(jù)持久化之mysql

同樣的矿酵,我們也把數(shù)據(jù)庫的配置信息唬复,寫在settings里

MYSQL_HOST = 'localhost'

MYSQL_USER = 'root'

MYSQL_PWD = 'pwd'

MYSQL_DB = 'dhname'

import pymysql

from jobboleproject.items import JobboleprojectItem

class JobboleprojectPipeline(object):

? ? def __init__(self,host,user,pwd,db):

? ? ? ? #創(chuàng)建mysql連接

? ? ? ? self.client = pymysql.Connect(host,user,pwd,db,charset='utf8')

? ? ? ? #創(chuàng)建游標(biāo)

? ? ? ? self.cursor = self.client.cursor()

? ? @classmethod

? ? def from_crawler(cls, crawler):

? ? ? ? host = crawler.settings['MYSQL_HOST']

? ? ? ? user = crawler.settings['MYSQL_USER']

? ? ? ? pwd = crawler.settings['MYSQL_PWD']

? ? ? ? db = crawler.settings['MYSQL_DB']

? ? ? ? return cls(host,user,pwd,db)

? ? def process_item(self,item,spider):

? ? ? ? data = dict(item)

? ? ? ? sql,parmars = item.insert_db_by_data(data)

? ? ? ? try:

? ? ? ? ? ? self.cursor.execute(sql,parmars)

? ? ? ? ? ? self.client.commit()

? ? ? ? except Exception as err:

? ? ? ? ? ? self.client.rollback()

? ? ? ? ? ? print(err)

? ? ? ? return item

? ? def close_spider(self,spider):

? ? ? ? self.cursor.close()

? ? ? ? self.client.close()

Scrapy Shell

scrapy還有一個(gè)交互終端,我們可以在未啟動(dòng)spider的情況下嘗試及調(diào)試代碼坏瘩,也可以用來測試XPath或CSS表達(dá)式盅抚,查看他們的工作方式漠魏,方便我們爬取的網(wǎng)頁中提取的數(shù)據(jù)倔矾。

啟動(dòng)

scrapy shell? 爬取目標(biāo)網(wǎng)頁

electors選擇器?Scrapy Selectors 內(nèi)置 XPath 和 CSS Selector 表達(dá)式機(jī)制?Selector有四個(gè)基本的方法,最常用的還是xpath:

xpath(): 傳入xpath表達(dá)式柱锹,返回該表達(dá)式所對應(yīng)的所有節(jié)點(diǎn)的selector list列表

extract(): 序列化該節(jié)點(diǎn)為字符串并返回list

css(): 傳入CSS表達(dá)式哪自,返回該表達(dá)式所對應(yīng)的所有節(jié)點(diǎn)的selector list列表,語法同 BeautifulSoup4

re(): 根據(jù)傳入的正則表達(dá)式對數(shù)據(jù)進(jìn)行提取禁熏,返回字符串list列表

scrapy -h 查看所有可用的命令:

scrapy view -h 查看view命令的詳細(xì)內(nèi)容:

scrapy list列出當(dāng)前項(xiàng)目中所有可用的spider

scrapy runspider xxxx.py在未創(chuàng)建項(xiàng)目的情況下壤巷,運(yùn)行一個(gè)編寫在Python文件中的spider。

scrapy version輸出Scrapy版本

Scrapy 的暫停和恢復(fù)

爬取大的站點(diǎn)瞧毙,我們希望能暫停爬取胧华,之后再恢復(fù)運(yùn)行寄症。

scrapy crawl 爬蟲名稱 -s JOBDIR=crawls/爬蟲名稱

如要暫停,直接Ctrl+C即可矩动,若要恢復(fù)有巧,再一次運(yùn)行此代碼即可

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市悲没,隨后出現(xiàn)的幾起案子篮迎,更是在濱河造成了極大的恐慌,老刑警劉巖示姿,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甜橱,死亡現(xiàn)場離奇詭異,居然都是意外死亡栈戳,警方通過查閱死者的電腦和手機(jī)岂傲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荧琼,“玉大人譬胎,你說我怎么就攤上這事∶” “怎么了堰乔?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脐恩。 經(jīng)常有香客問我镐侯,道長,這世上最難降的妖魔是什么驶冒? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任苟翻,我火速辦了婚禮,結(jié)果婚禮上骗污,老公的妹妹穿的比我還像新娘崇猫。我一直安慰自己,他們只是感情好需忿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布诅炉。 她就那樣靜靜地躺著,像睡著了一般屋厘。 火紅的嫁衣襯著肌膚如雪涕烧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天汗洒,我揣著相機(jī)與錄音议纯,去河邊找鬼。 笑死溢谤,一個(gè)胖子當(dāng)著我的面吹牛瞻凤,可吹牛的內(nèi)容都是我干的憨攒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼阀参,長吁一口氣:“原來是場噩夢啊……” “哼浓恶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起结笨,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤包晰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后炕吸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伐憾,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年赫模,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了树肃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瀑罗,死狀恐怖胸嘴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情斩祭,我是刑警寧澤劣像,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站摧玫,受9級特大地震影響耳奕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜诬像,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一屋群、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧坏挠,春花似錦芍躏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至喊熟,卻和暖如春柏肪,著一層夾襖步出監(jiān)牢的瞬間姐刁,已是汗流浹背芥牌。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留聂使,地道東北人壁拉。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓谬俄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親弃理。 傳聞我的和親對象是個(gè)殘疾皇子溃论,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容