scrapy框架

scrapy框架
Scrapy是用純Python實現一個為了爬取網站數據、提取結構性數據而編寫的應用框架,用途非常廣泛。

scrapy架構圖

scrapy各部分簡介:

Scrapy Engine(引擎): 負責信號和數據的傳遞,起協調作用.(框架幫我們實現了)

Scheduler(調度器): 會將Request請求任務,存儲在任務隊列中,引擎會從任務隊列中提取任務交給下載器 (框架幫我們實現了)

只有當調度器中不存在任何request了,整個程序才會停止,(也就是說,對于下載失敗的URL,Scrapy也會重新下載。)

Downloader(下載器):接收引擎傳遞過來的請求,發起請求,獲取響應,最終將響應結果交給spider爬蟲文件(框架幫我們實現了)

Spider(爬蟲):根據起始url發起請求,解析響應結果,第一獲取目標數據,第二提取新的url   (手動實現)

Item Pipeline(管道):將spider爬蟲文件yeild的item數據,做過濾和持久化  (手動實現的)

Downloader Middlewares(下載中間件):自定義下載組件(請求任務和響應結果都會經過下載中間件)代理中間件,cookies中間件,Uaer-Agent中間件,selenium中間件.. (特殊需求要手動實現)

Spider Middlewares(Spider中間件):可以自定義request請求和過濾Response響應  (特殊需求要手動實現)

安裝

sudo pip3 install scrapy

新建項目

scrapy startproject 爬蟲項目名稱

然后cd到spider文件夾下

新建爬蟲文件

crapy genspider 爬蟲文件名稱 域名:制作爬蟲開始爬取網頁

在這個時候我們項目的目錄結構應該會是這樣的

一個項目有5個文件我們一般情況下會進行修改

1.pipeline.py

做數據的過濾和持久化

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

它還要兩個可選方法

def open_spider(self,spider):

? ? ? ? 可選方法,在爬蟲開始執行的時候調用一次

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

? ? def close_spider(self,spider):

? ? ? ? 可選方法,在爬蟲結束的時候調用一次

? ? ? ? self.file.close()

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

2.item.py

根據目標網站,定義要提取的目標字段

3.spiders.py

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

name

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

allowed_domains

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

start_urls

? ? 初始URL元組/列表。當沒有制定特定的URL時,spider將從該列表中開始進行爬取。

start_requests(self)

? ? 該方法必須返回一個可迭代對象(iterable)。該對象包含了spider用于爬取(默認實現是使用 start_urls 的url)的第一個Request。

? ? 當spider啟動爬取并且未指定start_urls時,該方法被調用。

parse(self, response)

? ? 當請求url返回網頁沒有指定回調函數時,默認的Request對象回調函數。

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

4.settings.py

設置文件,可以在里面做User-Agent,Headers,激活管道文件等等

BOT_NAME

(也是項目名稱)。使用 startproject 命令創建項目時會被自動賦值。

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

爬蟲的文件路徑

USER_AGENT

用戶代理,一般設置這個參數用來偽裝瀏覽器請求

ROBOTSTXT_OBEY

是否遵守ROBOT協議,為False時,表示不遵守,

為True時表示遵守(默認為True)

COOKIES_ENABLED

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

cookies的請求,我們將這個參數設置為False,(默認為True)

DEFAULT_REQUEST_HEADERS

默認: 如下

{

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

'Accept-Language': 'en',

}

用于Scrapy HTTP請求的默認標頭

ITEM_PIPELINES

設置并激活管道文件,為了存儲數據使用,

后面的數字表示優先級,數字越小,優先級越高

關于日志信息的設置

LOG_ENABLED

默認: True

是否啟用logging。

LOG_FILE

默認: None

logging輸出的文件名。如果為None,則使用標準錯誤輸出(standard error)。

Logging使用

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

可以修改配置文件settings.py,任意位置添加下面兩行,效果會清爽很多。

LOG_FILE = "TencentSpider.log"

LOG_LEVEL = "INFO"

5.middleware.py

下載中間件和爬蟲中間件

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

主要有四種:

1.隨機User-Agent

2.自定義隨機cookies

3.enium結合使用

4.自定義隨機ip池

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

通用爬蟲和一般爬蟲的區別主要是多了一個Rule的規則

他的主要參數是:

LinkExtractor中有:

allow:一般設置一個正則表達式,符合該正則表達式的連接,提取該url(常用)

deny:同樣是跟一個正則表達式,符合該正則表達式的連接,不提取該url

(優先級比allow要高)

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

? deny_domains: 提取鏈接時,一定不能提取deny_domains設置的域下

restrict_xpaths:當提取鏈接的時候,我們可以使用xpath語法定位到某些標簽,提取標簽下,

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

tags:可以指定要提取哪些標簽

?attrs:可以指定要提取標簽的哪些屬性

?restrict_css:當提取鏈接的時候,我們可以使用css語法定位到某些標簽,提取標簽下,

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

還有:

callback='回調函數名稱',

?follow=True | False,? # 表示是否要跟進

爬蟲的步驟

step1:

分析目標網站,根據要提取的目標數據,在items.py中自定義字段

step2:

? ? 在爬蟲文件中:(1)首先設置目標url

? ? ? ? ? ? ? ? ????????????????(2) 解析請求成功的響應結果,提取目標數據,賦值給item,提取新的url,繼續發起請求

step3:

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

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

注意:

1.進入項目一定要先設置虛擬環境

2.首先更改settings的幾個配置

? ? (1).ROBOTSTXT_OBEY

是否遵守ROBOT協議,為False時,表示不遵守,

為True時表示遵守(默認為True)

(2).COOKIES_ENABLED

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

cookies的請求,我們將這個參數設置為False,(默認為True)

(3).DEFAULT_REQUEST_HEADERS

此設置是設置一個全局的請求頭

默認: 如下

{

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

'Accept-Language': 'en',

}

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

表示延時下載,一般情況下設為1或2

通用爬蟲:為了全站爬取

通用爬蟲創建項目

scrapy genspider -t crawl 爬蟲名稱 域

通用爬蟲與普通爬蟲的區別就在于多了一個rules規則

rules 規則屬性的參數:是一個元組,可以放多個Rule對象

創建Rule:

LinkExtractor:設置提取規則

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

callback:設置回調函數

follwer:是否跟進

process_links:設置一個函數,根據正則規則獲取的url,可以在回調函數中獲取到

processs_request:設置一個函數,可以在這個回調方法中攔截所有根據正則規則提取到的url構建的Request對象

注意:

1.設置回調的時候一定不能重寫parse方法

2.要獲取起始url的響應結果 ,必須重寫parse_start_url

3.在設置Rule對象的時候,如果沒有callback回調函數,默認表示跟進

什么情況下會用到通用爬蟲???

當我們提取數據的目標網站的網址很有規律,并且模塊很清晰,我么就可以使用通用爬蟲class

數據持久化之圖片下載

在 ImagesPipeline 類中實現,提供了一個方便并具有額外特性的方法,來下載并本地存儲圖片

首先在setttings里設置一個圖片下載路徑

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

第一種:正常的發起請求 ,獲取圖片的二進制文件,保存

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

? ? 重寫兩個方法:

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

? ? ? ? ? ? 獲取圖片地址,發起請求

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

? ? ? ? ? ? 在results結果中根據圖片下載狀態,獲取圖片本地存儲的路徑,

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

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

? ? 1.可以自定義數據管道

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

? ? ? ? ? ? # 可以設置一些參數,(比如,創健數據庫鏈接,打開文件等等

? ? ? ? @classmethod

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

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

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

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

? ? ? ? ? ? # 可選方法,在爬蟲個開啟的時候會調用

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

? ? ? ? ? ? # 所有的item都會經過這個方法

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

? ? ? ? ? ? # 方法一:

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

? ? ? ? ? ? ? ? 做數據插入操作

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

? ? ? ? ? ? ? ? 做數據插入操作

? ? ? ? ? ? 方法二:

? ? ? ? ? ? ? ? 1.在item對應的類中,我們定義一個方法,返回sql語句和要插入的數據

? ? ? ? ? ? ? ? 2.使用item調用這個方法,得到sql語句和要插入的數據

? ? ? ? ? ? ? ? 3.執行插入操作

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

數據持久化之mongodb

首先在settings設置數據庫配置文件

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

數據持久化之mysql

同樣的,我們也把數據庫的配置信息,寫在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):

? ? ? ? #創建mysql連接

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

? ? ? ? #創建游標

? ? ? ? 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還有一個交互終端,我們可以在未啟動spider的情況下嘗試及調試代碼,也可以用來測試XPath或CSS表達式,查看他們的工作方式,方便我們爬取的網頁中提取的數據。

啟動

scrapy shell? 爬取目標網頁

electors選擇器?Scrapy Selectors 內置 XPath 和 CSS Selector 表達式機制?Selector有四個基本的方法,最常用的還是xpath:

xpath(): 傳入xpath表達式,返回該表達式所對應的所有節點的selector list列表

extract(): 序列化該節點為字符串并返回list

css(): 傳入CSS表達式,返回該表達式所對應的所有節點的selector list列表,語法同 BeautifulSoup4

re(): 根據傳入的正則表達式對數據進行提取,返回字符串list列表

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

scrapy view -h 查看view命令的詳細內容:

scrapy list列出當前項目中所有可用的spider

scrapy runspider xxxx.py在未創建項目的情況下,運行一個編寫在Python文件中的spider。

scrapy version輸出Scrapy版本

Scrapy 的暫停和恢復

爬取大的站點,我們希望能暫停爬取,之后再恢復運行。

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

如要暫停,直接Ctrl+C即可,若要恢復,再一次運行此代碼即可

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容