[Python Scrapy爬蟲] 二.翻頁爬取農產品資訊並儲存本地
前面 "Python爬蟲之Selenium+Phantomjs+CasperJS" 介紹了很多Selenium基於自動測試的Python爬蟲程式,主要利用它的xpath語句,通過分析網頁DOM樹結構進行爬取內容,同時可以結合Phantomjs模擬瀏覽器進行滑鼠或鍵盤操作。但是,更為廣泛使用的Python爬蟲框架是——Scrapy爬蟲。這篇文章是一篇基礎文章,主要內容包括:
1.Scrapy爬取貴州農產品的詳細步驟;
2.Scrapy如何將資料儲存至Json或CSV檔案中;
3.Scrapy實現三種翻頁方法爬取農產品資料。
下面提供前面的一些相關文章:
官方 Scrapy : http://scrapy.org/
官方英文文件: http://doc.scrapy.org/en/latest/index.html
官方中文文件: https://scrapy-chs.readthedocs.org/zh_CN/0.24/index.html
入門安裝知識: [Python爬蟲] scrapy爬蟲系列 <一>.安裝及入門介紹
BeautifulSoup:[python爬蟲] BeautifulSoup爬取+CSV儲存貴州農產品資料
在做資料分析時,通常會遇到預測商品價格的情況,而在預測價格之前需要爬取海量的商品價格資訊,比如淘寶、京東商品等,這裡作者採用Scrapy技術爬取貴州農產品資料集。
輸入 "http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=1" 網址,開啟貴州農經網,可以檢視貴州各個地區農產品每天價格的波動情況,如下圖所示,主要包括五個欄位:品種名稱、價格、計量單位、所在市場、上傳時間。
Scrapy框架自定義爬蟲主要步驟如下:
- 在CMD命令列模型下建立爬蟲工程,即建立GZProject工程爬取貴州農經網。
- 在items.py檔案中定義我們要抓取的資料欄目,對應商品名稱、價格、計量單位等五個欄位。
- 通過瀏覽器審查元素功能分析所需爬取內容的DOM結構並定位HTML節點。
- 建立Spiders爬蟲檔案,定位並爬取所需內容。
- 分析網頁翻頁方法,併傳送多頁面跳轉爬取請求,不斷執行Spiders爬蟲直到結束。
- 設定pipelines.py檔案,將爬取的資料集儲存至本地Json檔案或CSV檔案中。
- 設定settings.py檔案,設定爬蟲的執行優先順序。
下面是完整的實現過程,重點知識是如何實現翻頁爬取及多頁面爬取,希望對您有幫助。
一. 建立工程
在Windows環境下,我們呼叫“Ctrl+R”快捷鍵開啟執行對話方塊,然後輸出“cmd”命令開啟命令列模式,然後呼叫“cd”命令去到某個目錄下,再呼叫“scrapy startproject GZProject”命令建立爬取貴州農經網產品資訊的爬蟲工程。
建立Scrapy爬蟲
scrapy startproject GZProject
在本地C盤根目錄建立的GZProject工程目錄如下圖所示,包括常見的檔案,如items.py、middlewares.py、pipelines.py、settings.py以及資料夾spiders等。
二. 設定items檔案
接在我們需要在items.py檔案中定義需要爬取的欄位,這裡主要是五個欄位,呼叫scrapy.item子類的 Field()函式建立欄位,程式碼如下所示。
items.py檔案的程式碼如下:
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class GzprojectItem(scrapy.Item):
num1 = scrapy.Field() #品種名稱
num2 = scrapy.Field() #價格
num3 = scrapy.Field() #計量單位
num4 = scrapy.Field() #所在市場
num5 = scrapy.Field() #上傳時間
接下來就是核心內容,通過分析網頁DOM結構並編寫對應Spiders爬蟲程式碼。
三. 瀏覽器審查元素
開啟任意瀏覽器,然後呼叫“審查元素”或“檢查”功能(該功能在不同瀏覽器中稱呼不同,但功能都是相似的)檢視所需爬取內容的HTML原始碼,比如Chrome瀏覽器定位方法如圖13.21所示。選中需要爬取元素,然後右鍵滑鼠,點選“檢查”按鈕,可以看到元素對應的HTML原始碼,比如圖中的右邊部分。
通過審查元素功能,我們可以發現每行資料都位於<tr>節點下,其class屬性為“odd gradeX”,如圖13.22所示,接著呼叫scrapy框架的xpath、css等功能進行爬取。
四. 建立Spiders爬蟲並執行
然後在spiders資料夾下建立一個Python檔案,主要用於實現Spider爬蟲程式碼,建立GZSpider.py檔案,工程目錄如下圖所示。
增加程式碼如下所示,在GZSpider類中定義了爬蟲名(name)為“gznw”,同時程式碼中allowed_domains表示所爬取網址的跟地址,start_urls表示開始爬取的網頁地址,然後呼叫parse()函式進行爬取,這裡首先爬取該網友的標題,通過response.xpath('//title')函式實現。程式碼如圖所示:
GZSpider.py
# -*- coding: utf-8 -*-
import scrapy
class GZSpider(scrapy.Spider):
name = "gznw" #貴州農產品爬蟲
allowed_domains = ["gznw.gov.cn"]
start_urls = [
"http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=1"
]
def parse(self, response):
for t in response.xpath('//title'):
title = t.extract()
print title
for t in response.xpath('//title/text()'):
title = t.extract()
print title
接下來進入C盤工程目錄,執行下列命令啟動Spider爬蟲。
cd GZProject
scrapy crawl gznw
"scrapy crawl gznw"啟動Spider爬蟲,爬取貴州農經網商品,執行如圖所示。程式開始執行,自動使用start_urls構造Request併傳送請求,然後呼叫parse()函式對其進行解析,在這個解析過程中可能會通過連結再次生成Request,如此不斷迴圈,直到返回的文字中再也沒有匹配的連結,或排程器中的Request物件用盡,程式才停止。
輸出結果如下所示,包括爬取的標題HTML原始碼“<title>貴州農經網</title>”和標題內容“貴州農經網”,如圖所示。
接下來我們需要爬取商品資訊,呼叫response.xpath('//tr[@class="odd gradeX"]')方法定位到class屬性為“odd gradeX”的tr節點,並分別獲取五個td節點,對應五個欄位內容。完整程式碼如下所示:
GZSpider.py
# -*- coding: utf-8 -*-
import scrapy
from scrapy import Request
from scrapy.selector import Selector
from GZProject.items import *
class GZSpider(scrapy.Spider):
name = "gznw" #貴州農產品爬蟲
allowed_domains = ["gznw.gov.cn"]
start_urls = [
"http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=1"
]
def parse(self, response):
print '----------------Start------------------'
print response.url
for sel in response.xpath('//tr[@class="odd gradeX"]'):
item = GzprojectItem()
num1 = sel.xpath('td[1]/text()').extract()[0]
num2 = sel.xpath('td[2]/text()').extract()[0]
num3 = sel.xpath('td[3]/text()').extract()[0]
num4 = sel.xpath('td[4]/text()').extract()[0]
num5 = sel.xpath('td[5]/text()').extract()[0]
print num1,num2,num3,num4,num5
item['num1'] = num1
item['num2'] = num2
item['num3'] = num3
item['num4'] = num4
item['num5'] = num5
yield item
print '\n'
輸出內容如下所示,同時呼叫“item = GzprojectItem()”程式碼宣告瞭欄目item,再呼叫“item['num1'] = num1”程式碼將爬取的資料儲存至欄目中。
----------------Start------------------
http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=1
獼猴桃 26 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
山楂 40 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
柿子 12 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
板栗 36 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
開心果 80 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
草莓 50 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
核桃 36 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
菜籽油 20 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
龍眼 20 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
車釐子 100 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:28
對應輸出內容如圖所示。
講到這裡,我們已經將貴州農經網第一頁的商品資訊爬取了,那其他頁面的資訊,不同日期的商品資訊如何爬取呢?Scrapy又怎麼實現跳轉翻頁爬蟲呢?
五. 實現翻頁功能及多頁面爬取
接下來我們講解Scrapy爬蟲的三種翻頁方法供大家學習。當然還有更多方法,比如利用Rule類定義網頁超連結的規則進行爬取,請讀者下來研究,這裡主要提供三種簡單的翻頁思想。
貴州農經網的超連結可以通過URL欄位“page=頁碼”實現翻頁,比如第二頁的超連結為“http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=2”,我們訪問該超連結就可以獲取第二頁的商品資訊,如下圖所示,訪問其他網頁的原理一樣。
方法一:定義URLs超連結列表單分別爬取
Scrapy框架是支援並行爬取的,其爬取速度非常快,如果讀者想爬取多個網頁,可以將網頁URL依次列在start_urls中。
# -*- coding: utf-8 -*-
import scrapy
from scrapy import Request
from scrapy.selector import Selector
from GZProject.items import *
class GZSpider(scrapy.Spider):
name = "gznw" #貴州農產品爬蟲
allowed_domains = ["gznw.gov.cn"]
start_urls = [
"http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=1",
"http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=2",
"http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=3"
]
def parse(self, response):
print '----------------Start------------------'
print response.url
for sel in response.xpath('//tr[@class="odd gradeX"]'):
item = GzprojectItem()
num1 = sel.xpath('td[1]/text()').extract()[0]
num2 = sel.xpath('td[2]/text()').extract()[0]
num3 = sel.xpath('td[3]/text()').extract()[0]
num4 = sel.xpath('td[4]/text()').extract()[0]
num5 = sel.xpath('td[5]/text()').extract()[0]
print num1,num2,num3,num4,num5
print '\n'
輸出如下圖所示,可以看到採用Scrapy爬取了三頁商品內容。
方法二:拼接不同網頁URL併傳送請求爬取
假設我們的URL很多,如果採用方法一顯然是不可行的,那麼怎麼處理呢?這裡我們提出了第二種方法,通過拼接不同網頁的URL,迴圈傳送請求進行爬取。拼接方法如下:
next_url="http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page="+str(i)
在parse()函式中定義一個while迴圈,通過“yield Request(next_url)”程式碼傳送新的爬取請求,並迴圈呼叫parse()函式進行爬取。完整程式碼如下所示:
GZSpider.py
# -*- coding: utf-8 -*-
import scrapy
from scrapy import Request
from scrapy.selector import Selector
from GZProject.items import *
class GZSpider(scrapy.Spider):
name = "gznw" #貴州農產品爬蟲
allowed_domains = ["gznw.gov.cn"]
start_urls = [
"http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=1"
]
def parse(self, response):
print '----------------Start------------------'
print response.url
for sel in response.xpath('//tr[@class="odd gradeX"]'):
item = GzprojectItem()
num1 = sel.xpath('td[1]/text()').extract()[0]
num2 = sel.xpath('td[2]/text()').extract()[0]
num3 = sel.xpath('td[3]/text()').extract()[0]
num4 = sel.xpath('td[4]/text()').extract()[0]
num5 = sel.xpath('td[5]/text()').extract()[0]
print num1,num2,num3,num4,num5
item['num1'] = num1
item['num2'] = num2
item['num3'] = num3
item['num4'] = num4
item['num5'] = num5
yield item
print '\n'
#迴圈換頁爬取
i = 2
while i<=10:
next_url = "http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page="+str(i)
i = i + 1
yield Request(next_url)
輸出部分結果如下所示:
----------------Start------------------
http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=8
豇豆 12 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
紅薯 12 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
老南瓜 15 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
菠菜 12 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
平菇/凍菌 20 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
貢梨 26 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
油菜薹 23 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
韭菜 15 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
綠豆(幹) 12 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
絲瓜 12 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
----------------Start------------------
http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=10
黃瓜 15 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
花生油 40 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
鵪鶉蛋 20 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:25
血橙 15 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:24
羊肉 240 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:24
蓮花白 6 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:24
小蔥 12 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:24
綠豆 25 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:24
麵粉(標準一級) 6 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:24
臍橙 15 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:24
----------------Start------------------
http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=6
羔蟹 50 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
草魚 50 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
青蛇果 36 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
紅蛇果 32 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
芒果 26 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
豬肉(肥瘦) 32 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
都勻毛尖 1,000 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
鯉魚 60 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
鰱魚 60 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
鱔魚 60 元/公斤 貴陽市息烽縣城區集貿市場 2018-02-09 14:22:26
方法三:獲取下一頁超連結請求爬取內容
下面講解另一種方法,獲取下一頁的超連結併傳送請求進行爬取。通過審查元素,我們可以看到“下一頁”對應的HTML原始碼如下圖所示。
這裡我們通過程式碼獲取class為“page-link next”的超連結(<a>),如果存在“下一頁”超連結,則進行跳轉爬取,如果“下一頁”超連結為空,則停止爬取。核心程式碼如下:
next_url = response.xpath('//a[@class="page-link next"]/@href').extract()
if next_url is not None:
next_url = 'http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx' + next_url[0]
yield Request(next_url, callback=self.parse)
爬取的結果為"?areaid=22572&page=3",再對獲取的超連結進行拼接,得到的URL為"http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx?areaid=22572&page=3",再呼叫Request()函式傳送請求,爬取內容。但由於貴州農經網有4萬多個頁面,建議大家設定爬取網頁的數量,程式碼如下:
i = 0
next_url = response.xpath('//a[@class="page=link next"]/@href').extract()
if next_(url is not None) and i<20:
i = i + 1
next_url = 'http://www.gznw.gov.cn/priceInfo/getPriceInfoByAreaId.jx' + next_url[0]
yield Request(next_url, callback=self.parse)
接下來告訴大家如何將爬取的資料儲存至本地。
六. 設定pipelines檔案儲存資料至本地
pipeLine檔案是用來對Spider返回的Item列表進行儲存操作,可以寫入到檔案或者資料庫中。pipeLine只有一個需要實現的方法:process_item,比如將我們的Item儲存到JSON格式檔案中,完整程式碼如下:
pipelines.py
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
import codecs
import json
class GzprojectPipeline(object):
def __init__(self):
self.file = codecs.open('guizhou.json', 'w', encoding='utf-8')
def process_item(self, item, spider):
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(line)
return item
def spider_closed(self, spider):
self.file.close()
呼叫codecs.open('guizhou.json', 'w', encoding='utf-8')函式將資料儲存至“guizhou.json”檔案中,最後設定settings.py檔案的優先順序。
七. 設定settings檔案
在該檔案中設定如下程式碼,將貴州農經網爬蟲的優先順序設定為1,優先順序範圍從1到1000,越小優先順序越高;“GZProject.pipelines.GzprojectPipeline”表示要設定的通道。
settings.py
ITEM_PIPELINES = {
'GZProject.pipelines.GzprojectPipeline': 1
}
最後輸入程式碼“scrapy crawl gznw”執行爬蟲,輸出部分結果如下所示。
同時,在本地建立的“guizhou.json”檔案中儲存資料如下所示,採用鍵值對形式顯示。
如果讀者想儲存為CSV檔案,則執行“scrapy crawl gznw -o gz.csv”,輸出截圖如下所示:
寫到這裡,一個完整的Scrapy爬取貴州農經網的農產品資料已經講完了,後面我也將繼續學習Rule類以及其不同頁面的爬取,甚至包括儲存至資料庫中。更多的爬蟲知識希望讀者下來結合實際需求和專案進行深入學習,並爬取所需的資料集。
相關文章
- [python爬蟲] BeautifulSoup爬取+CSV儲存貴州農產品資料Python爬蟲
- [python爬蟲] 招聘資訊定時系統 (一).BeautifulSoup爬取資訊並儲存MySQLPython爬蟲MySql
- 爬蟲 Scrapy框架 爬取圖蟲圖片並下載爬蟲框架
- 使用Scrapy爬取圖片入庫,並儲存在本地
- Python Scrapy 爬蟲(二):scrapy 初試Python爬蟲
- Scrapy爬蟲(6)爬取銀行理財產品並存入MongoDB(共12w+資料)爬蟲MongoDB
- Python爬蟲——實戰二:爬取天貓產品價格(逆向工程方法)Python爬蟲
- [python爬蟲] Selenium爬取內容並儲存至MySQL資料庫Python爬蟲MySql資料庫
- Scrapy之"並行"爬蟲並行爬蟲
- [python 爬蟲]第一個Python爬蟲,爬取某個新浪部落格所有文章並儲存為doc文件Python爬蟲
- python爬蟲——爬取大學排名資訊Python爬蟲
- 爬蟲實戰(二):Selenium 模擬登入並爬取資訊爬蟲
- Python爬蟲框架:scrapy爬取高考派大學資料Python爬蟲框架
- python爬蟲---網頁爬蟲,圖片爬蟲,文章爬蟲,Python爬蟲爬取新聞網站新聞Python爬蟲網頁網站
- python爬蟲怎麼翻頁Python爬蟲
- python爬蟲--爬取鏈家租房資訊Python爬蟲
- 初識Scrapy框架+爬蟲實戰(7)-爬取鏈家網100頁租房資訊框架爬蟲
- Java爬蟲翻頁Java爬蟲
- python爬蟲Scrapy框架Python爬蟲框架
- 【Python篇】scrapy爬蟲Python爬蟲
- Python爬蟲—Scrapy框架Python爬蟲框架
- 爬蟲--Scrapy簡易爬蟲爬蟲
- scrapy定製爬蟲-爬取javascript內容爬蟲JavaScript
- 儲存資料到MySql資料庫——我用scrapy寫爬蟲(二)MySql資料庫爬蟲
- Python爬蟲-用Scrapy框架實現漫畫的爬取Python爬蟲框架
- scrapy爬蟲爬蟲
- Python3爬蟲(十八) Scrapy框架(二)Python爬蟲框架
- python 爬蟲之requests爬取頁面圖片的url,並將圖片下載到本地Python爬蟲
- Python爬蟲爬取淘寶,京東商品資訊Python爬蟲
- 小白學 Python 爬蟲(25):爬取股票資訊Python爬蟲
- Python 爬蟲(六):使用 Scrapy 爬取去哪兒網景區資訊Python爬蟲
- Python爬蟲——實戰一:爬取京東產品價格(逆向工程方法)Python爬蟲
- 【知識積累】使用Httpclient實現網頁的爬取並儲存至本地HTTPclient網頁
- 爬蟲教程——用Scrapy爬取豆瓣TOP250爬蟲
- Python爬蟲筆記(4):利用scrapy爬取豆瓣電影250Python爬蟲筆記
- Python爬蟲實戰-使用Scrapy框架爬取土巴兔(一)Python爬蟲框架
- python網路爬蟲(14)使用Scrapy搭建爬蟲框架Python爬蟲框架
- Python爬蟲教程-30-Scrapy 爬蟲框架介紹Python爬蟲框架