今天對(duì)解析網(wǎng)頁(yè)數(shù)據(jù)最為常見三種方式進(jìn)行介紹:分別是Beautiful、正則表達(dá)式和xpath。其中xpath最為常用,也最為方便
基本知識(shí)點(diǎn):
bs4進(jìn)行數(shù)據(jù)解析
? ? -數(shù)據(jù)解析的原理:
? ? ? ? 1.標(biāo)簽定位
? ? ? ? 2.提取標(biāo)簽,標(biāo)簽屬性中存儲(chǔ)的數(shù)據(jù)值
? ? -bs4數(shù)據(jù)解析的原理:
? ? ? ? 1.實(shí)例化一個(gè)BeautifulSoup對(duì)象,并將頁(yè)面源碼數(shù)據(jù)加載在該對(duì)象中
? ? ? ? 2.通過調(diào)用BeautifulSoup對(duì)象中相關(guān)屬性或者方法進(jìn)行標(biāo)簽定位和數(shù)據(jù)提取
? ? -環(huán)境安裝:
? ? ? ? pip install bs4
? ? - 如何實(shí)例化BeautifulSoup對(duì)象:
? ? ? ? - from bs4 import BeautifulSoup
? ? ? ? - 對(duì)象的實(shí)例化:
? ? ? ? ? ? - 1. 將本地的html文檔中的數(shù)據(jù)加載到該對(duì)象中
? ? ? ? ? ? - 2. 將互聯(lián)網(wǎng)獲取的頁(yè)面源碼加載到該對(duì)象中
? ? ?- 提供的用于數(shù)據(jù)解析的方法與屬性:
? ? ? ? ? ? - soup.tagName:返回的是文檔中第一次出現(xiàn)的tagName對(duì)應(yīng)的標(biāo)簽(tagName為網(wǎng)頁(yè)中的標(biāo)簽名)
? ? ? ? ? ? - soup.find('tagName') 返回的也是文檔中第一次出現(xiàn)的tagName對(duì)應(yīng)的標(biāo)簽
? ? ? ? ? ? ? ? 注:find('tagName')中可以包含多個(gè)tagName參數(shù),使得能被準(zhǔn)確定位到
? ? ? ? ? ?- soup.find_all('tagName') 返回的是文檔中所有tagName部分(注:中間同樣可以包含多個(gè)tagName)
? ? ? ? ? ? - soup.select('某種選擇器(id,class,標(biāo)簽...選擇器)'),返回的是一個(gè)列表
? ? ? ? ? ? -層級(jí)選擇器:
? ? ? ? ? ? ? ? ?> 表示的是一個(gè)層級(jí)
? ? ? ? ? ? ? ? ?空格表示的是多個(gè)層級(jí)
? ? ? ? - 獲取標(biāo)簽之間的文本數(shù)據(jù):
? ? ? ? ? ? -soup.a.text/string/get_text()
? ? ? ? ? ? -text/get_text() 可以獲取一個(gè)標(biāo)簽中所有的文本內(nèi)容
? ? ? ? ? ? -string 只可以獲得該標(biāo)簽下直系的文本內(nèi)容
? ? ? ? - 獲取標(biāo)簽中的屬性值:
? ? ? ? ? ? -soup.a['href']
爬取任務(wù):詩(shī)詞名句網(wǎng)中的《三國(guó)演義》全文
網(wǎng)頁(yè)顯示如下:
代碼示例:
from bs4 import BeautifulSoupimport requestsif __name__ == '__main__':# 解析網(wǎng)頁(yè)所有內(nèi)容url = "http://www.shicimingju.com/book/sanguoyanyi.html"headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/75.0.3770.100 Safari/537.36 '}page_text = requests.get(url=url,headers=headers).text# 解析網(wǎng)頁(yè)上需要的東西(即章節(jié)詳情頁(yè)鏈接和章節(jié)標(biāo)題)soup = BeautifulSoup(page_text,'lxml')li_list = soup.select('.book-mulu > ul > li')fp = open('./三國(guó)演義.txt', 'w', encoding='utf-8')for li in li_list:# mile = []title = li.a.stringhref = li.a['href']page_text2 = requests.get(url="http://www.shicimingju.com"+href, headers=headers).text# print(page_text2)soup2 = BeautifulSoup(page_text2, 'lxml')p_list = soup2.find('div',class_="chapter_content")content = p_list.text#print(content)fp.write(title+":"+content+'\n')????????print(title,"爬取成功")
結(jié)果顯示:
2?正則表達(dá)式
基本知識(shí)點(diǎn)
- 字符
- [ab5@]
匹配"a"或"b"或"5"或"@" - [^abc]
匹配a、b、c之外的任意字符 - [f-k]
匹配“f"到"k"之間的字符 - [^A-F0-3]
匹配“A"-"F","0"-"3"之外的任意一個(gè)字符 - \d
任意一個(gè)數(shù)字,0~9 - \w
任意一個(gè)字母、數(shù)字、漢字或下劃線,A~Z、a~z、0~9、_和任意一個(gè)漢字 - \s
任意空白符,包括空格、制表符、換行符 - .
小數(shù)點(diǎn)可以匹配任意一個(gè)字符,換行除外(如果要匹配包括"\n"在內(nèi)的所有字符,一般用[\s\S]) - 普通字符:字母、數(shù)字、漢字、下劃線,匹配與之相同的一個(gè)字符
- 簡(jiǎn)單轉(zhuǎn)義字符:\n(換行),\t(制表),\\(\本身)和 \^...(\^等有特殊作用的符號(hào)如要匹配自己的話要用轉(zhuǎn)義)
- 標(biāo)準(zhǔn)字符集合
注意區(qū)分大小寫,大寫是相反的意思,匹配相反是不匹配 - 自定義字符集合
[ ]方括號(hào)匹配方式,能夠匹配方括號(hào)中的任意一個(gè)字符,^表示取反 - 量詞(Quantifier)?
修飾前面的一個(gè)表達(dá)式,如果要修飾多個(gè)表達(dá)式,就用( )把表達(dá)式包起來 - 貪婪模式 (默認(rèn))
匹配符合的最長(zhǎng)的字符串 - 非貪婪模式 (在量詞后面加 ? 例:{m,n}? )
匹配符合的最短的字符串 - {n}
表達(dá)式重復(fù)n次 - {m,n}
表達(dá)式至少重復(fù)m次,最多重復(fù)n次 - {m,}
表達(dá)式至少重復(fù)m次 - ?匹配表達(dá)式0或1次,相當(dāng)于{0,1}
- +表達(dá)式至少出現(xiàn)一次,相當(dāng)于{1,}
- *表達(dá)式不出現(xiàn)或出現(xiàn)任意次,相當(dāng)于{0,}
爬取任務(wù):糗圖百科中的“熱圖”
網(wǎng)頁(yè)顯示如下:
代碼示例:
import requestsimport reimport osif __name__ == '__main__':# 創(chuàng)建文件夾,用于存放所有圖片if not os.path.exists('./qiutu'):os.mkdir('./qiutu')baseurl = "https://www.qiushibaike.com/imgrank/page/"headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/75.0.3770.100 Safari/537.36 '}want_img = int(input("你想獲得幾頁(yè)圖片:"))if 13>= want_img > 0:for i in range(1,want_img+1):url = baseurl+str(i)# 獲取單張網(wǎng)頁(yè)response = requests.get(url=url,headers=headers)page_text = response.text# 定位解析專門的鏈接位置findimg = re.compile(r'<div class="thumb">.*?<img src="(.*?)" alt.*?</div>', re.S)img = re.findall(findimg,page_text) # 注意findall 的前面為re正則,后面為范圍for j in img:scr="https:"+j #真正的圖片鏈接img_data = requests.get(url=scr,headers=headers).content # 生成圖片# 生成圖片名稱img_name = scr.split('/')[-1] # 以圖片鏈接最后的部分作為名字# 圖片存儲(chǔ)的路徑img_path = './qiutu/'+img_namewith open(img_path,'wb') as fp:fp.write(img_data)print(img_name,"下載成功")print("一共有%d張"%(len(img)*want_img))else:????????print('對(duì)不起,鐵汁,沒這么多頁(yè)圖')
結(jié)果顯示:
3?xpath
基本知識(shí)點(diǎn):
xpath解析:最常用也是最便捷高效的一種解析方式,具有通用性。
? ? -xpath解析原理:
? ? ? ? -1.實(shí)例化一個(gè)etree的對(duì)象,且將需要被解析的頁(yè)面源碼數(shù)據(jù)加載到該對(duì)象中
? ? ? ? -2.調(diào)用etree對(duì)象中的xpath方法,結(jié)合著xpath表達(dá)式實(shí)現(xiàn)標(biāo)簽的定位以及內(nèi)容的捕獲。
? ? - 環(huán)境的安裝:
? ? ? ? - pip install lxml
? ? - 如何實(shí)例化一個(gè)etree對(duì)象
? ? ? ? -1.將本地的html文檔中的源碼數(shù)據(jù)加載到該對(duì)象中
? ? ? ? ? ? etree.parse(filePath)
? ? ? ? -2.可以將從互聯(lián)網(wǎng)上獲取的源碼數(shù)據(jù)加載到該對(duì)象中
? ? ? ? ? ? etree.HTML('page_text')
? ? ? ? - xpath('xpath表達(dá)式')
? ? -xpath表達(dá)式
? ? ? ? - .: 選取當(dāng)前節(jié)點(diǎn)
? ? ? ? - /:表示的是一個(gè)層級(jí),從根節(jié)點(diǎn)開始定位
? ? ? ? - //:表示的是多個(gè)層級(jí)。可以表示從任意位置開始定位
? ? ? ? - 屬性定位://tag[@屬性='']
? ? ? ? - 索引定位://tag[@屬性='']/p[3]? 索引是從1開始的
? ? ? ? - 取文本:
? ? ? ? ? ? - /text() 獲取的是標(biāo)簽中直系的文本內(nèi)容
? ? ? ? ? ? - //text() 獲取的是標(biāo)簽中非直系的文本內(nèi)容(標(biāo)簽中所有的文本內(nèi)容)
? ? ? ? - 取屬性:
? ? ? ? ? ? - /@attrName? ==>img/src
xpath方式爬取將在接下來的爬取案例中呈現(xiàn)
-?END?-
李
讀書、觀影
分享生活的碎片
? ? ? ? ? 有理想的人不會(huì)傷心