Scrapy簡介
Scrapy,Python開發的一個快速、高層次的螢幕抓取和web抓取框架,用於抓取web站點並從頁面中提取結構化的資料。Scrapy用途廣泛,可以用於資料探勘、監測和自動化測試。Scrapy吸引人的地方在於它是一個框架,任何人都可以根據需求方便的修改。它也提供了多種型別爬蟲的基類,如BaseSpider、sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支援。
Scrapy專案結構
scrapy.cfg: 專案的配置檔案 lianjia/: 該專案的python模組。之後您將在此加入程式碼。 lianjia/items.py: 專案中的item檔案. lianjia/pipelines.py: 專案中的pipelines檔案. lianjia/settings.py: 專案的設定檔案. lianjia/spiders/: 放置spider程式碼的目錄.
下面主要說一下幾個比較重要的: item.py
Item 是儲存爬取到的資料的容器。比如我下面將要爬取的鏈家網租房資訊的地點、平米數、價格,我會在item.py
檔案中定義相應的欄位。
from scrapy import Item,Field
class LianjiaItem(Item):
# define the fields for your item here like:
# name = scrapy.Field()
place=Field() #爬取鏈家租房資訊的-地點
size=Field() #爬取鏈家租房資訊的-房屋平米數
price = Field() # 爬取鏈家租房資訊的-價格
複製程式碼
spider.py
此檔案是我們在spiders檔案下自己建立的,用來寫爬蟲的程式碼的,非常重要。
我們需要建立一個Spider,必須繼承scrapy.Spider
,並有下面三個屬性:
name: 用於區別Spider。 該名字必須是唯一的,您不可以為不同的Spider設定相同的名字。 start_urls: 包含了Spider在啟動時進行爬取的url列表。 因此,第一個被獲取到的頁面將是其中之一。 後續的URL則從初始的URL獲取到的資料中提取。 parse() 是spider的一個方法。 被呼叫時,每個初始URL完成下載後生成的 Response 物件將會作為唯一的引數傳遞給該函式。 該方法負責解析返回的資料(response data),提取資料(生成item)以及生成需要進一步處理的URL的 Request 物件。 pipelines.py 主要作用是為爬取下的資料的做處理。比如txt或者存入資料庫的操作。 settings.py 主要是對爬蟲專案的設定
Scrapy框架爬蟲實戰
今天主要爬取一下鏈家網租房主頁的前一百頁資料,也是為了帶大家去入門熟悉一下Scrapy框架。
建立專案
命令列切換到你想建立Scrapy專案的路徑,我是在D盤pycharm資料夾建立的 輸入:
scrapy startproject 專案名稱
複製程式碼
然後我們用PyCharm匯入:File-->Open
爬取鏈家網詳解
1.編寫item.py
,定義爬取的欄位。我們爬取鏈家網條目的租房地點、平米數以及價位,所以定義三個欄位,程式碼如下:
from scrapy import Item,Field
class LianjiaItem(Item):
# define the fields for your item here like:
# name = scrapy.Field()
place=Field() #爬取鏈家租房資訊的-地點
size=Field() #爬取鏈家租房資訊的-房屋平米數
price = Field() # 爬取鏈家租房資訊的-價格
pass
複製程式碼
2.在spiders資料夾下建立spider.py
,用來爬取程式碼。程式碼如下:
import scrapy
from scrapy.http import Request
from lianjia.items import LianjiaItem
class LianjiaSpider(scrapy.Spider):#必須繼承scrapy.Spider
name = "lianjia" #名稱
start_urls = ['https://tj.lianjia.com/zufang/'] #URL列表
def parse(self, response):
item=LianjiaItem()
infos=response.xpath('//div[@class="info-panel"]')
for info in infos:
# 獲取地點
place = info.xpath('div/div/a[@class="laisuzhou"]/span/text()').extract()[0].replace('\xa0','')
# 獲取平米數
size = info.xpath('div/div/span[@class="meters"]/text()').extract()[0].replace('\xa0','')
# 獲取價格
price = info.xpath('div/div[@class="price"]/span/text()').extract()[0] + info.xpath(
'div/div[@class="price"]/text()').extract()[0]
item['place']=place
item['size'] = size
item['price'] = price
yield item #返回資料
#從新設定URL,從第2頁到第100頁 回撥parse方法
for i in range(2,101):
url = 'https://tj.lianjia.com/zufang/pg{}/'.format(str(i))
yield Request(url, callback=self.parse) ## 回撥
複製程式碼
通過程式碼我們會發現,Item欄位是通過Selector選擇器提取的。 它有四個基本的方法:
xpath(): 傳入xpath表示式,返回該表示式所對應的所有節點的selector list列表 。 css(): 傳入CSS表示式,返回該表示式所對應的所有節點的selector list列表. **extract(): **序列化該節點為unicode字串並返回list。 re(): 根據傳入的正規表示式對資料進行提取,返回unicode字串list列表。
另外也可以在Shell中除錯xpath等,具體的操作在下面,慢慢看。
3.txt形式儲存
pipelines.py
就是對爬取下的資料做處理的,所以我們可以在此檔案中寫txt或者資料庫儲存等等,今天就以TXT儲存為例:
class LianjiaPipeline(object):
def process_item(self, item, spider):
try:
place = str(item['place'])
size = str(item['size'])
price = str(item['price'])
fb = open("C:/Users/qzs/Desktop/qinzishuai.txt", "a+")
fb.write(place + size + price + '\n')
fb.close()
except:
pass
return item
複製程式碼
另外還需要在settings.py
中配置一下,名稱一定要換成你的專案名稱:
ITEM_PIPELINES = {
'lianjia.pipelines.LianjiaPipeline': 300, #儲存到txt檔案
}
複製程式碼
4.執行 執行scrapy專案兩種方式: (1).在Terminal輸入命令執行,也就是在專案路徑的命令列輸入:
scrapy crawl 專案名稱
複製程式碼
(2).在Pycharm中執行。我們要在scrapy.cfg
同層目錄下建一個begin.py
檔案,輸入程式碼:
from scrapy import cmdline
cmdline.execute("scrapy crawl lianjia".split())
複製程式碼
然後再點選Run-->Edit Configurations...
然後我們就可以執行了。 **強調:**第一次執行的時候,我遇到no module named win32API錯誤,這是因為Python沒有自帶訪問windows系統API的庫的,需要下載第三方庫。
直接在pip安裝即可:pip install pypiwin32
複製程式碼
安裝完成後執行成功,檢視TXT:
Scrapy Shell除錯xpath
快捷命令:
shelp() - 列印可用物件及快捷命令的幫助列表 fetch(request_or_url) - 根據給定的請求(request)或URL獲取一個新的response,並更新相關的物件 view(response) - 在本機的瀏覽器開啟給定的response。 其會在response的body中新增一個 tag ,使得外部連結(例如圖片及css)能正確顯示。 注意,該操作會在本地建立一個臨時檔案,且該檔案不會被自動刪除。
在命令列輸入:
scrapy shell "爬取的URL"
複製程式碼
然後會顯示你能內容如下,說明成功進入shell:
下面主要說一下response.xpath除錯,為了判斷我們的xpath是否正確。 例如我們想除錯一下鏈家網租房的地點資訊,輸入:response.xpath('//div/div/a[@class="laisuzhou"]/span/text()').extract()
複製程式碼
結果顯示:
說明我們的xpath沒有問題。 再可以輸入:view.(response)
複製程式碼
效果如下:
希望對大家有所幫助! 大家可以關注我的微信公眾號:「秦子帥」一個有質量、有態度的公眾號!