我們都知道,爬蟲獲取頁面的響應(yīng)之后,最關(guān)鍵的就是如何從繁雜的網(wǎng)頁中把我們需要的數(shù)據(jù)提取出來,
python從網(wǎng)頁中提取數(shù)據(jù)的包很多,常用的解析模塊有下面的幾個(gè):
- BeautifulSoup API簡(jiǎn)單 但解析速度慢,不推薦使用
- lxml 由C語言編寫的xml解析庫(libxm2),解析速度快 但是API復(fù)雜
- Scrapy 綜合以上兩者優(yōu)勢(shì)實(shí)現(xiàn)了自己的數(shù)據(jù)提取機(jī)制,被稱為Selector選擇器。
它是由lxml庫構(gòu)建的,并簡(jiǎn)化了API ,先通過XPath或者CSS選擇器選中要提取的數(shù)據(jù),然后進(jìn)行提取
Python資源共享群:484031800
Scrapy選擇器構(gòu)建于 lxml 庫之上,這意味著它們?cè)谒俣群徒馕鰷?zhǔn)確性上非常相似。
Selector選擇器的用法
下面我們以 Scrapy Shell 和 Scrapy 文檔服務(wù)器的一個(gè)樣例頁面(url= http://doc.scrapy.org/en/latest/_static/selectors-sample1.html ) 來了解選擇器的基本用法:
構(gòu)造選擇器
Scrapy selector 可以以 文字(Text),二進(jìn)制(content)或 TextResponse 構(gòu)造的 Selector。其根據(jù)輸入類型自動(dòng)選擇最優(yōu)的分析方法 以文字構(gòu)造:
?
在學(xué)習(xí)過程中有什么不懂得可以加我的 python學(xué)習(xí)交流扣扣qun,784758214 群里有不錯(cuò)的學(xué)習(xí)視頻教程、開發(fā)工具與電子書籍。 與你分享python企業(yè)當(dāng)下人才需求及怎么從零基礎(chǔ)學(xué)習(xí)好python,和學(xué)習(xí)什么內(nèi)容 url = "http://doc.scrapy.org/en/latest/_static/selectors-sample1.html" response = requests.get(url=url) selector = Selector(text=response.text)
以 response 構(gòu)造:
?
selector = Selector(response=response)
以二進(jìn)制構(gòu)造:
?
selector = Selector(text=response.content)
使用選擇器
這里強(qiáng)烈推薦使用 scrapy shell 來進(jìn)行調(diào)試!
為什么要使用 scrapy shell ?
當(dāng)我們需要爬取某個(gè)網(wǎng)站,然后提取數(shù)據(jù)的時(shí)候,要用到 xpath css 或者正則提取方法等
但是有時(shí)候這些xpath 或者css 語句不一定一次就能寫對(duì),有時(shí)候需要我們不斷地去調(diào)試。
可能有些人會(huì)說,我每寫一次然后重新去請(qǐng)求,輸出結(jié)果測(cè)試一下就知道了。只能說這種做法就比較愚蠢了,如果遇到那種容易封IP的網(wǎng)站,你這樣頻繁的去請(qǐng)求測(cè)試,測(cè)不了幾次,你的ip就被封了
這時(shí)候,我們要使用 scrapy shell 去調(diào)試,測(cè)試成功后,在拷貝到我們的項(xiàng)目中就可以了
如何使用 scrapy shell?
首先打開 Shell, 然后輸入命令 scrapy shell url
?
scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html
?
當(dāng)然在 pycharm中, 也可以使用
?
?
當(dāng) shell 載入后,將獲得名為 response 的 shell 變量,url 響應(yīng)的內(nèi)容保存在 response 的變量中,可以直接使用以下方法來獲取屬性值
?
response.body response.headers response.headers['Server']
?
?
由于在 response 中使用 XPath、CSS 查詢十分普遍,因此,Scrapy 提供了兩個(gè)實(shí)用的快捷方式:
?
response.css() response.xpath()
比如,我們獲取該網(wǎng)頁下的 title 標(biāo)簽,方法如下:
?
>>> response.css("title") [
] >>> response.xpath("http://title") [
]
.xpath() 以及 .css() 方法返回一個(gè)類 SelectList 的實(shí)例,它是一個(gè)新選擇器的列表。這個(gè) API 可以用來快速的提取嵌套數(shù)據(jù)。
為了提取真實(shí)的原文數(shù)據(jù),需要調(diào)用 .extract() 等方法
提取數(shù)據(jù)
extract():返回選中內(nèi)容的Unicode字符串。
extract_first():SelectorList專有,返回其中第一個(gè)Selector對(duì)象調(diào)用extract方法。通常SelectorList中只含有一個(gè)Selector對(duì)象的時(shí)候選擇調(diào)用該方法。
re() 使用正則表達(dá)式來提取選中內(nèi)容中的某部分。
舉個(gè)例子
?
>>> selector.xpath('.//b/text()') .extract() [‘價(jià)格:99.00元’,‘價(jià)格:88.00元’,‘價(jià)格:88.00元’] >>> selector.xpath('.//b/text()').re('\d+\.\d+') [ '99.00','88.00','88.00']
re_first() 返回SelectorList對(duì)象中的第一個(gè)Selector對(duì)象調(diào)用re方法。
?
>>> selector.xpath('.//b/text()').re_first('\d+\.\d+') '99.00'
css語法簡(jiǎn)單介紹
" * " 選擇所有節(jié)點(diǎn) " # container " 選擇id為container的節(jié)點(diǎn) " .container " 選擇class包含container的節(jié)點(diǎn) "li a " 選擇 所有 li 下的所有 a 節(jié)點(diǎn) "ul + p" 選擇所有ul后面的第一個(gè)p元素 "#container > ul" 選擇id為container的第一個(gè)ul節(jié)點(diǎn) "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']" 結(jié)尾是cn的a元素
我們以上面的樣例網(wǎng)頁為例 下面是樣例的html的源碼
?
Example website
css用法實(shí)例
?
>>> 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選取第一個(gè)a標(biāo)簽里面的href屬性 ['image1.html'] >>> response.xpath(".//div[@id='images']/a[1]").xpath("@href").extract() # xpath選取第一個(gè)a標(biāo)簽里面的href屬性 ['image1.html']
css用法實(shí)戰(zhàn)
目標(biāo)地址:中國大學(xué)校花網(wǎng) www.xiaohuar.com/hua/
爬蟲整體思路: 1、先將總頁數(shù)拿下來 2、根據(jù)總頁數(shù)循環(huán)去拿圖片地址 3、再請(qǐng)求圖片鏈接,將圖片保存到本地
F12打開瀏覽器開發(fā)者工具,找到尾頁再網(wǎng)頁源碼中的位置
?
?
可以看到尾頁鏈接在 a 標(biāo)簽列表里面的末尾,在 css 中我們可以使用切片的方法來獲取最后一個(gè)值 語法如下:
?
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
?
?
同樣的方法(不細(xì)說了),我們獲取圖片的地址和名稱 語法如下:
?
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("")
?
?
因?yàn)橹皇怯脕頊y(cè)試,所以我只爬了前幾頁,如果想爬全部,將循環(huán)的頁數(shù)改成 total_pages 即可 最終效果如下:
?
?
如果你依然在編程的世界里迷茫,可以加入我們的Python學(xué)習(xí)扣qun:784758214,看看前輩們是如何學(xué)習(xí)的!交流經(jīng)驗(yàn)!自己是一名高級(jí)python開發(fā)工程師,從基礎(chǔ)的python腳本到web開發(fā)、爬蟲、django、數(shù)據(jù)挖掘等,零基礎(chǔ)到項(xiàng)目實(shí)戰(zhàn)的資料都有整理。送給每一位python的小伙伴!分享一些學(xué)習(xí)的方法和需要注意的小細(xì)節(jié),點(diǎn)擊加入我們的python學(xué)習(xí)者聚集地
不到2分鐘,就全部爬完了,因?yàn)槭桥老x入門的教程,所以就沒用異步的爬蟲框架,下面是源碼
?
# 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] # 總頁數(shù) 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) # 創(chuàng)建選擇器 self.parse_html(selector) # 解析網(wǎng)頁 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: # 第一個(gè)圖片和其他圖片地址不一樣 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:\\測(cè)試\\校花") # 需要先在本地創(chuàng)建此目錄 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)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

