Python爬虫之解析网页
常用的類(lèi)庫(kù)為lxml, BeautifulSoup, re(正則)
以獲取豆瓣電影正在熱映的電影名為例,url='https://movie.douban.com/cinema/nowplaying/beijing/'
網(wǎng)頁(yè)分析
部分網(wǎng)頁(yè)源碼
<ul class="lists"><liid="3878007"class="list-item"data-title="海王"data-score="8.2"data-star="40"data-release="2018"data-duration="143分鐘"data-region="美國(guó) 澳大利亞"data-director="溫子仁"data-actors="杰森·莫瑪 / 艾梅柏·希爾德 / 威廉·達(dá)福"data-category="nowplaying"data-enough="True"data-showed="True"data-votecount="105013"data-subject="3878007">分析可知我們要的電影名稱(chēng)信息在li標(biāo)簽的data-title屬性里
下面開(kāi)始寫(xiě)代碼
爬蟲(chóng)源碼展示
import requests from lxml import etree # 導(dǎo)入庫(kù) from bs4 import BeautifulSoup import reimport time# 定義爬蟲(chóng)類(lèi) class Spider():def __init__(self):self.url = 'https://movie.douban.com/cinema/nowplaying/beijing/'self.headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'}r = requests.get(self.url,headers=self.headers)r.encoding = r.apparent_encodingself.html = r.textdef lxml_find(self):'''用lxml解析'''start = time.time() # 三種方式速度對(duì)比selector = etree.HTML(self.html) # 轉(zhuǎn)換為lxml解析的對(duì)象titles = selector.xpath('//li[@class="list-item"]/@data-title') # 這里返回的是一個(gè)列表for each in titles:title = each.strip() # 去掉字符左右的空格print(title)end = time.time()print('lxml耗時(shí)', end-start)def BeautifulSoup_find(self):'''用BeautifulSoup解析'''start = time.time()soup = BeautifulSoup(self.html, 'lxml') # 轉(zhuǎn)換為BeautifulSoup的解析對(duì)象()里第二個(gè)參數(shù)為解析方式titles = soup.find_all('li', class_='list-item')for each in titles:title = each['data-title']print(title)end = time.time()print('BeautifulSoup耗時(shí)', end-start)def re_find(self):'''用re解析'''start = time.time()titles = re.findall('data-title="(.+)"',self.html)for each in titles:print(each)end = time.time()print('re耗時(shí)', end-start)if __name__ == '__main__':spider = Spider()spider.lxml_find()spider.BeautifulSoup_find()spider.re_find()輸出結(jié)果
海王 無(wú)名之輩 無(wú)敵破壞王2:大鬧互聯(lián)網(wǎng) 狗十三 驚濤颶浪 毒液:致命守護(hù)者 憨豆特工3 神奇動(dòng)物:格林德沃之罪 恐龍王 老爸102歲 生活萬(wàn)歲 進(jìn)擊的男孩 摘金奇緣 亡命救贖 一百年很長(zhǎng)嗎 云上日出 誰(shuí)是壞孩子 照相師 緣·夢(mèng) 網(wǎng)絡(luò)謎蹤 龍貓 印度合伙人 綠毛怪格林奇 最萌警探 春天的馬拉松 lxml耗時(shí) 0.007623910903930664 海王 無(wú)名之輩 無(wú)敵破壞王2:大鬧互聯(lián)網(wǎng) 狗十三 驚濤颶浪 毒液:致命守護(hù)者 憨豆特工3 神奇動(dòng)物:格林德沃之罪 恐龍王 老爸102歲 生活萬(wàn)歲 進(jìn)擊的男孩 摘金奇緣 亡命救贖 一百年很長(zhǎng)嗎 超時(shí)空大冒險(xiǎn) 天渠 愛(ài)不可及 二十歲 你好,之華 冒牌搭檔 鐵甲戰(zhàn)神 克隆人 恐怖快遞 中國(guó)藍(lán)盔 阿凡提之奇緣歷險(xiǎn) 名偵探柯南:零的執(zhí)行人 為邁克爾·杰克遜鑄造雕像 再見(jiàn)仍是朋友 心迷宮 淡藍(lán)琥珀 阿拉姜色 兩個(gè)俏公主 云上日出 誰(shuí)是壞孩子 照相師 緣·夢(mèng) 網(wǎng)絡(luò)謎蹤 龍貓 印度合伙人 綠毛怪格林奇 最萌警探 春天的馬拉松 BeautifulSoup耗時(shí) 0.061043500900268555 海王 無(wú)名之輩 無(wú)敵破壞王2:大鬧互聯(lián)網(wǎng) 狗十三 驚濤颶浪 毒液:致命守護(hù)者 憨豆特工3 神奇動(dòng)物:格林德沃之罪 恐龍王 老爸102歲 生活萬(wàn)歲 進(jìn)擊的男孩 摘金奇緣 亡命救贖 一百年很長(zhǎng)嗎 超時(shí)空大冒險(xiǎn) 天渠 愛(ài)不可及 二十歲 你好,之華 冒牌搭檔 鐵甲戰(zhàn)神 克隆人 恐怖快遞 中國(guó)藍(lán)盔 阿凡提之奇緣歷險(xiǎn) 名偵探柯南:零的執(zhí)行人 為邁克爾·杰克遜鑄造雕像 再見(jiàn)仍是朋友 心迷宮 淡藍(lán)琥珀 阿拉姜色 兩個(gè)俏公主 云上日出 誰(shuí)是壞孩子 照相師 緣·夢(mèng) 網(wǎng)絡(luò)謎蹤 龍貓 印度合伙人 綠毛怪格林奇 最萌警探 春天的馬拉松 re耗時(shí) 0.0004856586456298828代碼說(shuō)明
1. lxml
lxml是通過(guò)xpath來(lái)查找
使用前需使用調(diào)用ertee.HTML()方法('()'內(nèi)填HTML代碼)生成一個(gè)可查找的對(duì)象
常用xpath語(yǔ)法如下
// 兩個(gè)斜杠為向下查找孫子標(biāo)簽
/ 一個(gè)斜杠為查找直接兒子標(biāo)簽
[] 方括號(hào)內(nèi)填標(biāo)簽屬性,如查找class屬性為name的a標(biāo)簽,格式為a[@class="name"]
/text() 取出標(biāo)簽的內(nèi)容,如查找網(wǎng)頁(yè)中的 <a class="name">KAINHUCK</a> 中的KAINHUCK,格式為//a[@class="name"]/text()
/@attr 取出標(biāo)簽的屬性,如查找網(wǎng)頁(yè)中的 <a class="name">KAINHUCK</a> 中的class屬性值name,格式為//a[@class="name"]/@class
2. BeautifulSoup
使用前需先將HTML轉(zhuǎn)換為課查找對(duì)象,格式為
BeautifulSoup(html, 'lxml')
html 為HTML代碼, 后面的參數(shù)為轉(zhuǎn)換方法(其他方法有'html.parser' , 'html5lib', 推薦使用'lxml')
查找方法
info = find('a', id='kain') 查找第一個(gè)id屬性為kain的a標(biāo)簽,并存進(jìn)info變量中(其他標(biāo)簽同理)
find_all('a', class_='name') 查找所有class屬性為name的a標(biāo)簽(注:class屬性需寫(xiě)成'class_')
info.p.text 獲取第一個(gè)id屬性為kain的a標(biāo)簽下的p標(biāo)簽的內(nèi)容(info為上面例子里的info,其他同理)
info.p['name'] 獲取第一個(gè)id屬性為kain的a標(biāo)簽下的p標(biāo)簽的name屬性值(info為上面例子里的info,其他同理)
當(dāng)代碼中有很多同級(jí)標(biāo)簽時(shí)
<p class='info-list'><a class='name'>text1</a><a class='name'>text2</a><a class='name'>text3</a><a class='name'>text4</a></p>示例代碼如下
from bs4 import BeautifulSouphtml = '''<p class='info-list'><a class='name'>text1</a><a class='name'>text2</a><a class='name'>text3</a><a class='name'>text4</a></p> ''' soup = BeautifulSoup(html, 'lxml') texts = soup.find('p', class_='info-list') print(texts.contents[1].text) # 輸出text1 print(texts.contents[2].text) # 輸出text2 print(texts.contents[3].text) # 輸出text3 print(texts.contents[4].text) # 輸出text4注意:不是從0開(kāi)始
3. re(正則表達(dá)式)
正則表達(dá)式內(nèi)容較多,大家可以參考這里
總結(jié)
使用lxml查找時(shí)可以在目標(biāo)網(wǎng)頁(yè)按F12調(diào)出開(kāi)發(fā)者窗口然后再在按Ctrl+f查找,在查找欄里輸入你的xpath語(yǔ)法可以檢查是否能找到對(duì)應(yīng)內(nèi)容
可以從看例子的輸出中看出三種方法的速度
lxml耗時(shí) 0.007623910903930664
BeautifulSoup耗時(shí) 0.061043500900268555
re耗時(shí) 0.0004856586456298828
對(duì)以上三種最常用的解析網(wǎng)頁(yè)的方法做個(gè)對(duì)比
| 語(yǔ)法難易度 | 簡(jiǎn)單 | 簡(jiǎn)單 | 復(fù)雜 |
| 查找速度 | 較快 | 慢 | 快 |
綜上,對(duì)于網(wǎng)頁(yè)內(nèi)容的解析,這里推薦新手使用lxml方法,而對(duì)速度有要求就使用正則表達(dá)式(入門(mén)有點(diǎn)困難)
轉(zhuǎn)載于:https://www.cnblogs.com/kainhuck/p/10090448.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Python爬虫之解析网页的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 浦发VISA白金卡简约版年费是多少?如何
- 下一篇: Python自建collections模