11scrapy
一. Scrapy基礎概念
Scrapy是一個為了爬取網站資料,提取結構性資料而編寫的應用框架,我們只需要實現少量的程式碼,就能夠快速的抓取。Scrapy 使用了 Twisted非同步網路框架,可以加快我們的下載速度。
二. 操作
1. 基本操作
1)建立一個scrapy專案
scrapy startproject mySpider
2)生成一個爬蟲
scrapy genspider itcast "itcast.cn”
3)提取資料
完善spider,使用xpath等方法
4)儲存資料
pipeline中儲存資料
2. 完善spdier
3. spdier資料傳到pipeline
4. 使用·pipeline
5. 設定log
為了讓我們自己希望輸出到終端的內容能容易看一些:
我們可以在setting中設定log級別
在setting中新增一行(全部大寫):LOG_LEVEL = "WARNING”
預設終端顯示的是debug級別的log資訊
三. 實行翻頁操作
1. 獲取地址,使用scrapy.Request方法
需要傳遞資料時,可以在方法中傳遞meta:
yield scrapy.Request(next_page_url,callback=self.parse,meta=…)
dont_filter:讓scrapy不會過濾當前url
四. 定義Item
1. 方法
2. 例項
3. 在不同的解析函式中傳遞引數
五. 深入pipeline
可以將一些需要初始化的數值新增在open_spider方法中
而close_spider可以做一些收尾工作
六. CrawlSpider
1. 功能
1)我們把滿足某個條件的url地址傳給rules,同時能夠指定callback函式。不需要手動去找下一頁的url地址,達到簡化程式碼的目的
2)生成CrawlSpider的命令
scrapy genspider –t crawl 專案名 “域名”
2. 例項
rules內的幾個引數:
1) LinkExtractor 連線提取器,提取url地址
2) callback 提取出來的url地址的response會交給callback來處理
3) follow 當前url地址的響應是否重新進rules來提取url地址
3. 注意點
七. Scrapy模擬登入
1. 攜帶cookie登入
1)直接攜帶cookie,在瀏覽器登入之後獲取檢查裡邊cookies的值
2)找到傳送post請求的url地址,帶上資訊,傳送請求
可以在settings裡邊新增引數【COOKIES_DEBUG=True】觀察cookies的傳遞過程。
不能把cookies放在headers中
2. 使用FormRequest
1) scrapy.FormRequest(url,formdata={},callback) formdata請求體
2) formdata裡邊的資料,可以試著在瀏覽器輸入使用者名稱和密碼之後,在session的Headers裡邊找到formdata,接著在Elements中查詢對應的元件
3)示例
3. 自動尋找Form表單中action的url
1) scrapy.FormRequest.from_response(response,formdata={},callback)
2) 示例
八. 案例分析
1. 貼吧爬蟲
1.1 補充不完整的連結
注意:需要匯入import urllib
通過urljoin方法自動把連結補全
1.2 對圖片解碼以及翻頁時處理內容覆蓋的問題
1) 圖片解碼:需要import requests
item["img_list"] = [requests.utils.unquote(i).split("src=")[-1] for i in item["img_list"]]
2) 翻頁使用extend()來處理
item["img_list"].extend(response.xpath("//img[@class='BDE_Image']/@src").extract())
1.3 spider下的tb.py完整程式碼
import scrapy import urllib import requests class TbSpider(scrapy.Spider): name = 'tb' allowed_domains = ['tieba.baidu.com'] start_urls = ['http://tieba.baidu.com/mo/q----,sz@320_240-1-3---2/m?kw=%E6%9D%8E%E6%AF%85&lp=9001'] def parse(self, response): #根據帖子進行分組 div_list = response.xpath("//div[contains(@class,'i')]") for div in div_list: item = {} item["href"] = div.xpath("./a/@href").extract_first() item["title"] = div.xpath("./a/text()").extract_first() item["img_list"] = [] if item["href"] is not None: item["href"] = urllib.parse.urljoin(response.url,item["href"]) yield scrapy.Request( item["href"], callback=self.parse_detail, meta = {"item":item} ) #列表頁的翻頁 next_url = response.xpath("//a[text()='下一頁']/@href").extract_first() if next_url is not None: next_url = urllib.parse.urljoin(response.url,next_url) yield scrapy.Request( next_url, callback=self.parse, ) def parse_detail(self,response): item = response.meta["item"] # if "img_list" not in item: #item["img_list"] = response.xpath("//img[@class='BDE_Image']/@src").extract() # else: item["img_list"].extend(response.xpath("//img[@class='BDE_Image']/@src").extract()) next_url = response.xpath("//a[text()='下一頁']/@href").extract_first() if next_url is not None:#表示由下一頁 next_url = urllib.parse.urljoin(response.url,next_url) yieldscrapy.Request( next_url, callback=self.parse_detail, meta={"item":item} ) else: item["img_list"] = [requests.utils.unquote(i).split("src=")[-1] for i in item["img_list"]] print(item) # yield item