我們都知道,爬蟲獲取頁面的響應之后,最關鍵的就是如何從繁雜的網頁中把我們需要的數據提取出來,
python從網頁中提取數據的包很多,常用的解析模塊有下面的幾個:
- BeautifulSoup API簡單 但解析速度慢,不推薦使用
- lxml 由C語言編寫的xml解析庫(libxm2),解析速度快 但是API復雜
- Scrapy 綜合以上兩者優勢實現了自己的數據提取機制,被稱為Selector選擇器。
它是由lxml庫構建的,并簡化了API ,先通過XPath或者CSS選擇器選中要提取的數據,然后進行提取
Python資源共享群:484031800
Scrapy選擇器構建于 lxml 庫之上,這意味著它們在速度和解析準確性上非常相似。
Selector選擇器的用法
下面我們以 Scrapy Shell 和 Scrapy 文檔服務器的一個樣例頁面(url= http://doc.scrapy.org/en/latest/_static/selectors-sample1.html ) 來了解選擇器的基本用法:
構造選擇器
Scrapy selector 可以以 文字(Text),二進制(content)或 TextResponse 構造的 Selector。其根據輸入類型自動選擇最優的分析方法 以文字構造:
?
在學習過程中有什么不懂得可以加我的 python學習交流扣扣qun,784758214 群里有不錯的學習視頻教程、開發工具與電子書籍。 與你分享python企業當下人才需求及怎么從零基礎學習好python,和學習什么內容 url = "http://doc.scrapy.org/en/latest/_static/selectors-sample1.html" response = requests.get(url=url) selector = Selector(text=response.text)
以 response 構造:
?
selector = Selector(response=response)
以二進制構造:
?
selector = Selector(text=response.content)
使用選擇器
這里強烈推薦使用 scrapy shell 來進行調試!
為什么要使用 scrapy shell ?
當我們需要爬取某個網站,然后提取數據的時候,要用到 xpath css 或者正則提取方法等
但是有時候這些xpath 或者css 語句不一定一次就能寫對,有時候需要我們不斷地去調試。
可能有些人會說,我每寫一次然后重新去請求,輸出結果測試一下就知道了。只能說這種做法就比較愚蠢了,如果遇到那種容易封IP的網站,你這樣頻繁的去請求測試,測不了幾次,你的ip就被封了
這時候,我們要使用 scrapy shell 去調試,測試成功后,在拷貝到我們的項目中就可以了
如何使用 scrapy shell?
首先打開 Shell, 然后輸入命令 scrapy shell url
?
scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html
?
當然在 pycharm中, 也可以使用
?
?
當 shell 載入后,將獲得名為 response 的 shell 變量,url 響應的內容保存在 response 的變量中,可以直接使用以下方法來獲取屬性值
?
response.body response.headers response.headers['Server']
?
?
由于在 response 中使用 XPath、CSS 查詢十分普遍,因此,Scrapy 提供了兩個實用的快捷方式:
?
response.css() response.xpath()
比如,我們獲取該網頁下的 title 標簽,方法如下:
?
>>> response.css("title") [
] >>> response.xpath("http://title") [
]
.xpath() 以及 .css() 方法返回一個類 SelectList 的實例,它是一個新選擇器的列表。這個 API 可以用來快速的提取嵌套數據。
為了提取真實的原文數據,需要調用 .extract() 等方法
提取數據
extract():返回選中內容的Unicode字符串。
extract_first():SelectorList專有,返回其中第一個Selector對象調用extract方法。通常SelectorList中只含有一個Selector對象的時候選擇調用該方法。
re() 使用正則表達式來提取選中內容中的某部分。
舉個例子
?
>>> selector.xpath('.//b/text()') .extract() [‘價格:99.00元’,‘價格:88.00元’,‘價格:88.00元’] >>> selector.xpath('.//b/text()').re('\d+\.\d+') [ '99.00','88.00','88.00']
re_first() 返回SelectorList對象中的第一個Selector對象調用re方法。
?
>>> selector.xpath('.//b/text()').re_first('\d+\.\d+') '99.00'
css語法簡單介紹
" * " 選擇所有節點 " # container " 選擇id為container的節點 " .container " 選擇class包含container的節點 "li a " 選擇 所有 li 下的所有 a 節點 "ul + p" 選擇所有ul后面的第一個p元素 "#container > ul" 選擇id為container的第一個ul節點 "a[class] " 選取所有有class屬性的a元素 "a[href="b.com"]" 含有href="b.com"的a元素 "a[href*='job'] " 包含job的a元素 "a[href^='https'] " 開頭是https的a元素 "a[href$='cn']" 結尾是cn的a元素
我們以上面的樣例網頁為例 下面是樣例的html的源碼
?
Example website
css用法實例
?
>>> response.css("title ::text").extract_first('') # 獲取文本 'Example website' >>> response.css("#images ::attr(href)").extract() # 獲取 id= images 下的所有href屬性 ['image1.html', 'image2.html', 'image3.html', 'image4.html', 'image5.html'] >>> response.css('a[href*=image]::attr(href)').extract() # 獲取所有包含 image 的 href 屬性 ['image1.html', 'image2.html', 'image3.html', 'image4.html', 'image5.html'] >>> response.css("#images a")[0].css("::attr(href)").extract() # css選取第一個a標簽里面的href屬性 ['image1.html'] >>> response.xpath(".//div[@id='images']/a[1]").xpath("@href").extract() # xpath選取第一個a標簽里面的href屬性 ['image1.html']
css用法實戰
目標地址:中國大學校花網 www.xiaohuar.com/hua/
爬蟲整體思路: 1、先將總頁數拿下來 2、根據總頁數循環去拿圖片地址 3、再請求圖片鏈接,將圖片保存到本地
F12打開瀏覽器開發者工具,找到尾頁再網頁源碼中的位置
?
?
可以看到尾頁鏈接在 a 標簽列表里面的末尾,在 css 中我們可以使用切片的方法來獲取最后一個值 語法如下:
?
total_pages = selector.css(".page_num a")[-1:].css("::attr(href)").re(r".*?(\d+).html")[0] # css total_pages = selector.xpath(".//div[@class='page_num']/a")[-1:].xpath("@href").re(r".*?(\d+).html")[0] # xpath
?
?
同樣的方法(不細說了),我們獲取圖片的地址和名稱 語法如下:
?
img_list = selector.css(".item_list.infinite_scroll .item_t .img") for img in img_list: title = img.css("a img ::attr(alt)").extract_first("") src = img.css("a img ::attr(src)").extract_first("")
?
?
因為只是用來測試,所以我只爬了前幾頁,如果想爬全部,將循環的頁數改成 total_pages 即可 最終效果如下:
?
?
如果你依然在編程的世界里迷茫,可以加入我們的Python學習扣qun:784758214,看看前輩們是如何學習的!交流經驗!自己是一名高級python開發工程師,從基礎的python腳本到web開發、爬蟲、django、數據挖掘等,零基礎到項目實戰的資料都有整理。送給每一位python的小伙伴!分享一些學習的方法和需要注意的小細節,點擊加入我們的python學習者聚集地
不到2分鐘,就全部爬完了,因為是爬蟲入門的教程,所以就沒用異步的爬蟲框架,下面是源碼
?
# coding: utf-8 import requests import time from scrapy import Selector import os class XiaoHuaSpider(object): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' } def spider(self): """ 爬蟲入口 :return: """ url = "http://www.xiaohuar.com/hua/" response = requests.get(url, headers=self.headers) selector = Selector(text=response.text) total_pages = selector.css(".page_num a")[-1:].css("::attr(href)").re(r".*?(\d+).html")[0] # 總頁數 self.parse_html(selector) # 第一頁爬取 for page in range(1, 5): # 第二頁至第五頁 url = f"http://www.xiaohuar.com/list-1-{page}.html" response = requests.get(url, headers=self.headers) selector = Selector(text=response.text) # 創建選擇器 self.parse_html(selector) # 解析網頁 def parse_html(self, selector): img_list = selector.css(".item_list.infinite_scroll .item_t .img") for img in img_list: title = img.css("a img ::attr(alt)").extract_first("") src = img.css("a img ::attr(src)").extract_first("") if "file" in src: # 第一個圖片和其他圖片地址不一樣 src = "http://www.xiaohuar.com" + src img_res = requests.get(src, headers=self.headers) data = img_res.content self.save_img(title, data) @staticmethod def save_img(title, data): """ 保存圖片到本地 :param title: :param data: :return: """ os.chdir("F:\\測試\\校花") # 需要先在本地創建此目錄 if os.path.exists(title + ".jpg"): print(f"{title}已存在") else: print(f"正在保存{title}") with open(title + ".jpg", "wb")as f: f.write(data) if __name__ == '__main__': spider = XiaoHuaSpider() t1 = time.time() spider.spider() t2 = time.time() print(t2 - t1)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
