免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Python網(wǎng)絡(luò)爬蟲(一)

一.理解網(wǎng)絡(luò)爬蟲

1.1爬蟲的定義

       網(wǎng)絡(luò)爬蟲又稱為網(wǎng)頁蜘蛛、網(wǎng)絡(luò)機(jī)器人。網(wǎng)絡(luò)爬蟲是一種按照一定的規(guī)則自動(dòng)的抓取網(wǎng)絡(luò)信息的程序或者腳本。通俗的說,就是根據(jù)一定的算法實(shí)現(xiàn)編程開發(fā),主要通過URL實(shí)現(xiàn)數(shù)據(jù)的抓取和挖掘。

1.2爬蟲的類型

     根據(jù)系統(tǒng)結(jié)構(gòu)和開發(fā)技術(shù)大致可分為4種類型:

     (1)通用網(wǎng)絡(luò)爬蟲,又稱為全網(wǎng)爬蟲,常見的有百度,Google等。

     (2)聚焦網(wǎng)絡(luò)爬蟲,又稱主題網(wǎng)絡(luò)爬蟲,是選擇性的爬行根據(jù)需求的主題相關(guān)頁面的網(wǎng)絡(luò)爬蟲。

     (3)增量式網(wǎng)絡(luò)爬蟲。是指對(duì)已下載網(wǎng)頁采取增量式更新和只爬行新產(chǎn)生或者已經(jīng)發(fā)生變化的網(wǎng)頁的爬蟲,它能夠在一定程度上保證所爬行的頁面盡可能是新的頁面。只會(huì)在需要的時(shí)候爬行新產(chǎn)生或發(fā)生更新的頁面,并不重新下載沒有發(fā)生變化的頁面,這類爬蟲在實(shí)際中不太普及。

     (4)深層網(wǎng)絡(luò)爬蟲。是大部分內(nèi)容不能通過靜態(tài)URL獲取的,隱藏在表單后的,只有用戶提交一些關(guān)鍵詞才能獲得的網(wǎng)絡(luò)頁面。

        這四類大致又可以分為兩類,通用爬蟲和聚焦爬蟲。聚焦網(wǎng)絡(luò)爬蟲,增量式網(wǎng)絡(luò)爬蟲和深層網(wǎng)絡(luò)爬蟲可歸為一類,因?yàn)樗麄兪嵌ㄏ蚺老x數(shù)據(jù)。而通用爬蟲在網(wǎng)絡(luò)上稱為搜索引擎。

        爬蟲的設(shè)計(jì)思路:

        (1) 明確需要爬取的網(wǎng)頁的URL地址;

        (2)通過http請(qǐng)求來獲取對(duì)應(yīng)的HTML頁面;

        (3)提取HTML的內(nèi)容。若是有用的數(shù)據(jù),就保存起來;若是繼續(xù)爬取的頁面,就重新指定第(2)步。

二.爬蟲開發(fā)基礎(chǔ)

2.1 HTTP與HTTPS

       http是一個(gè)簡(jiǎn)單的請(qǐng)求-響應(yīng)協(xié)議,它通常運(yùn)行在TCP之上。它指定了客戶端可能發(fā)送給服務(wù)器什么樣的消息以及得到什么樣的響應(yīng)??蛻舳耸墙K端用戶,服務(wù)器端是網(wǎng)站。通常使用web瀏覽器,網(wǎng)絡(luò)爬蟲或者其他工具,客戶端會(huì)發(fā)起一個(gè)到服務(wù)器上指定的http請(qǐng)求。這個(gè)客戶端就叫做用戶代理(User Agent)。一旦收到請(qǐng)求,服務(wù)器會(huì)發(fā)回一個(gè)狀態(tài)行(如“http/1.1 200 OK”)和 響應(yīng)的 消息,其中消息的內(nèi)容可能是請(qǐng)求的文件,錯(cuò)誤消息或者其他消息。

       http協(xié)議傳輸?shù)臄?shù)據(jù)都是未加密的,因此使用http協(xié)議傳輸隱私信息非常不安全。

       https協(xié)議傳輸?shù)臄?shù)據(jù)都是加密的。在傳輸數(shù)據(jù)之前需要客戶端與服務(wù)端之間進(jìn)行一次握手,在握手過程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息。

2.2 請(qǐng)求頭

       請(qǐng)求頭描述客戶端向服務(wù)器發(fā)送請(qǐng)求時(shí)使用的協(xié)議類型,所使用的編碼以及發(fā)送內(nèi)容的長(zhǎng)度等。檢測(cè)請(qǐng)求頭是常見的反爬蟲策略。因?yàn)榉?wù)器會(huì)對(duì)請(qǐng)求頭做一次檢測(cè)來判斷此次請(qǐng)求是人為的還是非人為的。所以我們?cè)诿看伟l(fā)送請(qǐng)求時(shí)都添加上請(qǐng)求頭。

     請(qǐng)求頭的參數(shù)如下:

    (1)Accept:瀏覽器可以接收的類型

    (2)Accept-Charset:編碼類型

    (3)Accept-Encoding:可以接收壓縮編碼類型

    (4)Accept-Language:可以接收的語言和國家類型

    (5)Host:請(qǐng)求的主機(jī)地址和端口

    (6)Referer:請(qǐng)求來自于那個(gè)頁面的URL

    (7)User-Agent:瀏覽器相關(guān)信息

    (8)Cookie:瀏覽器暫存服務(wù)器發(fā)送的信息

    (9)Connection:http請(qǐng)求版本的特點(diǎn)

   (10)Date:請(qǐng)求網(wǎng)站的時(shí)間

2.3 cookies

       它是指某些網(wǎng)站為了辯護(hù)用戶身份,進(jìn)行session跟蹤而存儲(chǔ)在用戶本地終端上的數(shù)據(jù)。一個(gè)cookies就是存儲(chǔ)在用戶主機(jī)瀏覽器 的文本文件。

       服務(wù)器可以利用cookies包含的信息判斷在http傳輸中的狀態(tài)。

2.4 JSON

      JSON(JavaScript Object Notation, JS 對(duì)象簡(jiǎn)譜) 是一種輕量級(jí)的數(shù)據(jù)交換格式。它基于ECMAScript (歐洲計(jì)算機(jī)協(xié)會(huì)制定的js規(guī)范)的一個(gè)子集,采用完全獨(dú)立于編程語言的文本格式來存儲(chǔ)和表示數(shù)據(jù)。簡(jiǎn)潔和清晰的層次結(jié)構(gòu)使得 JSON 成為理想的數(shù)據(jù)交換語言。 易于人閱讀和編寫,同時(shí)也易于機(jī)器解析和生成,并有效地提升網(wǎng)絡(luò)傳輸效率。

例如:

{"name": "John Doe", "age": 18, "address": {"country" : "china", "zip-code": "10000"}}

2.5 JavaScript

       JavaScript(簡(jiǎn)稱“JS”) 是一種具有函數(shù)優(yōu)先的輕量級(jí),解釋型或即時(shí)編譯型的高級(jí)編程語言。是一種解釋性腳本語言(代碼不進(jìn)行預(yù)編譯), 主要用來向HTML標(biāo)準(zhǔn)通用標(biāo)記語言下的一個(gè)應(yīng)用)頁面添加交互行為。

       JavaScript還能根據(jù)用戶觸發(fā)某些事件對(duì)用戶的操作進(jìn)行加工處理。要在爬蟲實(shí)現(xiàn)一些功能,就要分析JS如何執(zhí)行整個(gè)用戶登錄過程。

2.6 Ajax

        Ajax 不是一種新的編程語言,而是一種用于創(chuàng)建更好更快以及交互性更強(qiáng)的Web應(yīng)用程序的技術(shù)。使用 JavaScript 向服務(wù)器提出請(qǐng)求并處理響應(yīng)而不阻塞用戶核心對(duì)象XMLHttpRequest。通過這個(gè)對(duì)象,您的 JavaScript 可在不重載頁面的情況與 Web 服務(wù)器交換數(shù)據(jù),即在不需要刷新頁面的情況下,就可以產(chǎn)生局部刷新的效果。
        Ajax 在瀏覽器與 Web 服務(wù)器之間使用異步數(shù)據(jù)傳輸(HTTP 請(qǐng)求),這樣就可使網(wǎng)頁從服務(wù)器請(qǐng)求少量的信息,而不是整個(gè)頁面。
        判斷網(wǎng)頁數(shù)據(jù)是否使用ajax的方法:觸發(fā)事件之后,判斷網(wǎng)頁是否發(fā)生刷新狀態(tài)。若網(wǎng)頁沒有發(fā)生刷新,數(shù)據(jù)就自動(dòng)生成,說明數(shù)據(jù)的加載是通過ajax生成并渲染到網(wǎng)頁上的。反之,數(shù)據(jù)是通過服務(wù)器后臺(tái)生成并加載的。

三.Fiddler抓包工具

       Fiddler是一個(gè)http協(xié)議調(diào)試代理工具,它能夠記錄并檢查所有你的電腦和互聯(lián)網(wǎng)之間的http通訊,設(shè)置斷點(diǎn),查看所有的“進(jìn)出”Fiddler的數(shù)據(jù)(指cookie,html,js,css等文件)。

3.1 fiddler安裝配置

       在官網(wǎng)網(wǎng)站下載(https://www.telerik.com/download/fiddler),界面如下圖所示:

       配置fiddler,使其能夠抓取https請(qǐng)求信息:

(1)打開菜單-tools-fidder options-https

(2)勾選https中的選項(xiàng),然后點(diǎn)擊actions-trust root certificate,完成整數(shù)驗(yàn)證。

3.2 fiddler抓取手機(jī)應(yīng)用

    fiddler可通過同一無線網(wǎng)絡(luò)實(shí)現(xiàn)對(duì)手機(jī)應(yīng)用的抓包,手機(jī)抓包主要通過遠(yuǎn)程連接實(shí)現(xiàn)手機(jī)和fiddler通信。

    實(shí)現(xiàn)fiddler抓取手機(jī)應(yīng)用的步驟如下:

(1)配置fiddler遠(yuǎn)程連接模式。打開菜單欄:tools--fiddler options--connections,把allow remote computers to connect勾選上。

(2)在手機(jī)端進(jìn)行參數(shù)配置。要連接在同一個(gè)IP地址上(cmd中輸入ipconfig查看IP地址)

(3)在手機(jī)瀏覽器中輸入電腦IP地址和fiddler端口,點(diǎn)擊確認(rèn)后跳轉(zhuǎn)到證書下載頁面,點(diǎn)擊下載fiddlerroot certificate.

(4)證書文件以cer為后綴名,完成證書安裝后,進(jìn)入手機(jī)當(dāng)前連接WiFi詳情,設(shè)置代理IP,主機(jī)名為電腦IP地址,端口為fiddler配置的端口。

四.開始爬蟲

4.1 urllib模塊

        在python3中不存在urllib2模塊,同一為urllib。urllib模塊有如下四個(gè)子模塊:

1 urllib.request:用來打開和讀取URL。
2 urllib.error:包含了urllib.request產(chǎn)生的異常。
3 urllib.parse:用來解析和處理URL。
4 urllib.robotparse:用于解析robots.txt文件。

 urllib的方法及使用:

1 urllib.urlopen(url[, data[, proxies[,timeout[, context]]]]) 
功能說明:urllib是用于訪問URL的唯一方法  
參數(shù)解釋:
url :一個(gè)完整的遠(yuǎn)程資源路徑,一般是一個(gè)網(wǎng)站。
data:默認(rèn)值為none。若參數(shù)data為none,則代表請(qǐng)求方式為get,反之請(qǐng)求方式為post,發(fā)送post請(qǐng)求。參數(shù)data以字典形式存儲(chǔ)數(shù)據(jù),并將參數(shù)data由字典類型轉(zhuǎn)換成字節(jié)類型才能完成post請(qǐng)求。 proxies : 設(shè)置代理 timeout:超時(shí)設(shè)置 context:描述各種SSL選項(xiàng)的實(shí)例。
2 urllib.request.Request(url,data=none,headers={},method=none)
功能說明:聲明一個(gè)request對(duì)象,該對(duì)象可定義header等請(qǐng)求信息
參數(shù)解釋:
headers:設(shè)置request請(qǐng)求頭信息
method:設(shè)定請(qǐng)求方式,主要是get和post
"""urllib的使用"""
import
urllib.request # 向指定URL發(fā)送請(qǐng)求,獲取響應(yīng)。 response = urllib.request.urlopen('http://httpbin.org/anything') # 獲取響應(yīng)內(nèi)容 content = response.read().decode('utf-8') print(content) print(type(response)) # 響應(yīng)碼 print(response.status) # 響應(yīng)頭信息 print(response.headers)
# 導(dǎo)入urllib
import urllib.request
url = 'https://movie.douban.com/'
# 自定義請(qǐng)求頭
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)'
    'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
    'Referer': 'https://movie.douban.com/',
    'Connection': 'keep-alive'}
# 設(shè)置request的請(qǐng)求頭
req = urllib.request.Request(url, headers=headers)
# 使用urlopen打開req
html = urllib.request.urlopen(req).read().decode('utf-8')
# 寫入文件
f = open('code2.txt', 'w', encoding='utf8')
f.write(html)
f.close()

4.2 requests模塊

       requests模塊是在urllib的基礎(chǔ)上做了封裝,具備urllib的全部功能,讓使用者更加方便的使用。 

       安裝:pip install requests

4.2.1 發(fā)出請(qǐng)求

    有兩種方式:requests.get()requests.post()方法

1 requests.get(url, params=none, **kwargs)
2 requests.post(url, data=none, json=none, **kwargs)

   requests提供如下方法獲取響應(yīng)內(nèi)容:

 1 r.status_code:響應(yīng)狀態(tài)碼(200表示訪問成功,4**表示失?。? 2 r.raw:原始響應(yīng)體,使用r.raw.read()讀取
 3 r.content:字節(jié)方式的響應(yīng)體,需要進(jìn)行解碼
 4 r.text:字符串方式的響應(yīng)體,會(huì)自動(dòng)根據(jù)響應(yīng)頭部的字符編碼進(jìn)行解碼
 5 r.headers:以字典對(duì)象存儲(chǔ)服務(wù)器響應(yīng)頭,若鍵不存在,則返回none
 6 r.json():requests中內(nèi)置的json解碼器
 7 r.raise_for_status():請(qǐng)求失?。ǚ?00響應(yīng)),拋出異常
 8 r.url:獲取請(qǐng)求鏈接
 9 r.cookies:獲取請(qǐng)求后的cookies
10 r.encoding:獲取編碼格式
"""使用requests發(fā)送請(qǐng)求和攜帶參數(shù)"""

import requests

r = requests.get('https://httpbin.org/get')  # 發(fā)送get請(qǐng)求
print(r.text)

# 發(fā)送post請(qǐng)求,并帶參數(shù)
r = requests.get('https://httpbin.org/get', params={'key1': 'value1', 'key2': 'value2'})
print(r.text)

# 發(fā)送post請(qǐng)求,并傳遞參數(shù)
r = requests.post('https://httpbin.org/post', data={'key': 'value'})
print(r.text)

# 其他HTTP請(qǐng)求類型:PUT,DELETE,HEAD和OPTIONS
r = requests.put('https://httpbin.org/put', data={'key': 'value'})
print(r.text)

r = requests.delete('https://httpbin.org/delete')
print(r.text)

r = requests.head('https://httpbin.org/get')
print(r.text)

r = requests.options('https://httpbin.org/get')
print(r.text)

 4.2.2 復(fù)雜的請(qǐng)求方式

(1)添加請(qǐng)求頭
import requests
headers = {
    'content-type': 'application/json',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0'}
requests.get("https://www.baidu.com/", headers=headers)

(2)使用代理IP
import requests
proxies = {
  "http": "http://10.10.1.10:3128",
  "https": "http://10.10.1.10:1080",
}
requests.get("https://www.baidu.com/", proxies=proxies)
(3)證書驗(yàn)證
import requests
url = 'https://kyfw.12306.cn/otn/leftTicket/init'
# 關(guān)閉證書驗(yàn)證
r = requests.get(url, verify=False)
print(r.status_code)
# 開啟證書驗(yàn)證
# r = requests.get(url, verify=True)
# 設(shè)置證書所在路徑
# r = requests.get(url, verify= '/path/to/certfile')
4)超時(shí)設(shè)置
requests.get("https://www.baidu.com/", timeout=2)
requests.post("https://www.baidu.com/", timeout=2)

(5)使用cookies
import requests temp_cookies='JSESSIONID_GDS=y4p7osFr_IYV5Udyd6c1drWE8MeTpQn0Y58Tg8cCONVP020y2N!450649273;name=value' cookies_dict = {} for i in temp_cookies.split(';'): value = i.split('=') cookies_dict [value[0]] = value[1] r = requests.get(url, cookies=cookies) print(r.text)

4.2.3 錯(cuò)誤和異常

   若出現(xiàn)網(wǎng)絡(luò)問題,則請(qǐng)求將引發(fā)connectionerror異常。

   若http請(qǐng)求返回不成功的狀態(tài)碼,則將會(huì)引發(fā)httperror異常。

   若請(qǐng)求超時(shí),則會(huì)引起超時(shí)異常。

   若請(qǐng)求超過配置的最大重定向數(shù),則會(huì)引發(fā)TooManyRedirects異常。

   請(qǐng)求顯示引發(fā)的所有異常都繼承自requests.exceptions.RequestException。

4.3 re模塊

       正則表達(dá)式是對(duì)字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個(gè)“規(guī)則字符串”,這個(gè)“規(guī)則字符串”用來表達(dá)對(duì)字符串的一種過濾邏輯。

       正則表達(dá)式是對(duì)字符串(包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為“元字符”))操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個(gè)“規(guī)則字符串”,這個(gè)“規(guī)則字符串”用來表達(dá)對(duì)字符串的一種過濾邏輯。正則表達(dá)式是一種文本模式,該模式描述在搜索文本時(shí)要匹配的一個(gè)或多個(gè)字符串。

       語法請(qǐng)參考:https://www.runoob.com/regexp/regexp-tutorial.html

4.3.1 模塊內(nèi)容

1. re.match(pattern, string[, flags])

       這個(gè)方法將會(huì)從string(我們要匹配的字符串)的開頭開始,嘗試匹配pattern,一直向后匹配,如果遇到無法匹配的字符,立即返回None,如果匹配未結(jié)束已經(jīng)到達(dá)string的末尾,也會(huì)返回None。兩個(gè)結(jié)果均表示匹配失敗,否則匹配pattern成功,同時(shí)匹配終止,不再對(duì)string向后匹配。

"""match方法"""

import re

# match在起始位置匹配
ret = re.match('www', 'www.example.com')
print(type(ret))
# 獲取匹配的內(nèi)容
print(ret.group())
# 獲取匹配內(nèi)容在原字符串里的下標(biāo)
print(ret.span())
# 匹配不成功,返回None
print(re.match('com', 'www.example.com'))

line = "Cats are smarter than dogs"
matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I)
if matchObj:
    print("matchObj.group() : ", matchObj.group())
    # 獲取第一組的內(nèi)容
    print("matchObj.group(1) : ", matchObj.group(1))
    print("matchObj.group(2) : ", matchObj.group(2))
else:
    print("No match!!")

 

參數(shù)說明:
· pattern:匹配的正則表達(dá)式
· string:要匹配的字符串
· flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式,如是否區(qū)分大小寫,是否多行匹配等。
flags參數(shù)可選值:
· re.I: 忽略大小寫(括號(hào)內(nèi)是完整寫法,下同)
· re.M: 多行模式,改變'^''$'的行為(參見上圖)
· re.S: 點(diǎn)任意匹配模式,改變'.'的行為
· re.L: 使預(yù)定字符類 \w \W \b \B \s \S 取決于當(dāng)前區(qū)域設(shè)定
· re.U: 使預(yù)定字符類 \w \W \b \B \s \S \d \D 取決于unicode定義的字符屬性
· re.X: 詳細(xì)模式。這個(gè)模式下正則表達(dá)式可以是多行,忽略空白字符,并可以加入注釋。

2. re.search(pattern, string[, flags])

    search方法與match方法極其類似,區(qū)別在于match()函數(shù)只檢測(cè)re是不是在string的開始位置匹配,search()會(huì)掃描整個(gè)string查找匹配,match()只有在0位置匹配成功的話才有返回,如果不是開始位置匹配成功的話,match()就返回None。同樣,search方法的返回對(duì)象同樣match()返回對(duì)象的方法和屬性。

"""search方法"""

import re

# search查找第一次出現(xiàn)
ret = re.search('www', 'www.aaa.com www.bbb.com')
print(type(ret))
print(ret.group())
print(ret.span())
#匹配不成功,返回None
print(re.search('cn', 'www.aaa.com www.bbb.com'))


line = "Cats are smarter than dogs";
searchObj = re.search(r'(.*) are (.*?) .*', line, re.M | re.I)
if searchObj:
    print("searchObj.group() : ", searchObj.group())
    print("searchObj.group(1) : ", searchObj.group(1))
    print("searchObj.group(2) : ", searchObj.group(2))
else:
    print("Nothing found!!")

 

3. re.findall(pattern, string[, flags])

    搜索string,以列表形式返回全部能匹配的子串。

"""findall方法"""

import re

# 查找數(shù)字
result1 = re.findall(r'\d+','baidu 123 google 456')
result2 = re.findall(r'\d+','baidu88oob123google456')

print(result1)
print(result2)

 

4. re.finditer(pattern, string[, flags])

    搜索string,返回一個(gè)順序訪問每一個(gè)匹配結(jié)果(Match對(duì)象)的迭代器。

"""finditer方法"""

import re

#返回一個(gè)迭代器,可以循環(huán)訪問,每次獲取一個(gè)Match對(duì)象
it = re.finditer(r"\d+", "12a32bc43jf3")
for match in it:
    print(match.group())

 

5. re.split(pattern, string[, maxsplit])

    按照能夠匹配的子串將string分割后返回列表。maxsplit用于指定最大分割次數(shù),不指定將全部分割。

6. re.sub(pattern, repl, string, count=0, flags=0)

 

"""sub方法"""

import re

phone = "2004-959-559 # 這是一個(gè)國外電話號(hào)碼"

# 刪除字符串中的 Python注釋
num = re.sub(r'#.*$', "", phone)
print("電話號(hào)碼是: ", num)

# 刪除非數(shù)字(-)的字符串
num = re.sub(r'\D', "", phone)
print("電話號(hào)碼是 : ", num)


# 將匹配的數(shù)字乘以 2
def double(matched):
    value = int(matched.group('value'))
    return str(value * 2)


s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))

 

 

 

參數(shù)說明:
1
repl:用于替換的字符串 2 string:要被替換的字符串 3 count:替換的次數(shù)

7. re.subn(pattern, repl, string[, count])

    與sub()函數(shù)一致,返回結(jié)果是一個(gè)元組。

8. re.compile(pattern[, flags])

    該函數(shù)用于編譯正則表達(dá)式生成一個(gè)正則表達(dá)式(pattern)對(duì)象,供match()和search()等函數(shù)使用。

"""compile方法"""


import re

# 用于匹配至少一個(gè)數(shù)字
pattern = re.compile(r'\d+')
# 查找頭部,沒有匹配
m = pattern.match('one12twothree34four')
print(m)
# 從'e'的位置開始匹配,沒有匹配
m = pattern.match('one12twothree34four', 2, 10)
print(m)
# 從'1'的位置開始匹配,正好匹配,返回一個(gè) Match 對(duì)象
m = pattern.match('one12twothree34four', 3, 10)
print(m)
# 可省略 0
print(m.group(0))

 

 4.4BeautifulSoup4模塊

  4.4.1 簡(jiǎn)介  

     Beautiful Soup,有了它我們可以很方便地提取出 HTML 或 XML 標(biāo)簽中的內(nèi)容。BeautifulSoup是一個(gè)高效的網(wǎng)頁解析庫,可以從 HTML 或 XML 文件中提取數(shù)據(jù)。

beautifulsoup支持不同的解析器,比如,對(duì)HTML解析,對(duì)XML解析,對(duì)HTML5解析。一般情況下,我們用的比較多的是 lxml 解析器。

  4.4.2 安裝

1 pip install beautifulsoup4

使用時(shí)導(dǎo)入:

1 from bs4 import BeautifulSoup

4.4.3 BeautifulSoup庫解析器

解析器 使用方法 條件
bs4的HTML解析器 BeautifulSoup(html,'html.parser') 安裝bs4庫
lxml的HTML解析器 BeautifulSoup(html,'lxml') pip install lxml
lxml的XML解析器
BeautifulSoup(html,'xml') pip install lxml
html5lib的解析器 BeautifulSoup(html,'htmlslib') pip install html5lib

  4.4.4 使用

"""將字符串解析為HTML文檔解析"""

from bs4 import BeautifulSoup

html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a  class="sister" id="link1"><!-- Elsie --></a>,
<a  class="sister" id="link2">Lacie</a> and
<a  class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""

# 創(chuàng)建BeautifulSoup對(duì)象解析html,并使用lxml作為xml解析器soup = BeautifulSoup(html, 'lxml')

# 格式化輸出soup對(duì)象的內(nèi)容
print(soup.prettify())
例一:
"""
bs4實(shí)例測(cè)試""" from bs4 import BeautifulSoup import re html = """ <html><head><title>The Dormouse's story</title></head> <body> <p class="title" name="dromouse"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a class="sister" id="link1"><!-- Elsie --></a>, <a class="sister" id="link2">Lacie</a> and <a class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p> """ # 創(chuàng)建對(duì)象 soup = BeautifulSoup(html, 'lxml') # 獲取Tag對(duì)象 # 查找的是在所有內(nèi)容中的第一個(gè)符合要求的標(biāo)簽 print(soup.title) print(type(soup.title)) print(soup.p) # 標(biāo)簽的名字 print(soup.p.name) # 標(biāo)簽的屬性,可獲取,也可以設(shè)置 print(soup.p.attrs) print(soup.p.attrs['class']) # 文本 print(soup.p.string) # content屬性得到子節(jié)點(diǎn),列表類型 print(soup.body.contents) # children屬性屬性得到子節(jié)點(diǎn),可迭代對(duì)象 print(soup.body.children) # descendants屬性屬性得到子孫節(jié)點(diǎn),可迭代對(duì)象 print(soup.body.descendants) # find_all 查找所有符合要求的 name是按照標(biāo)簽名字查找 print(soup.find_all(name='b')) print(soup.find_all(name=['a', 'b'])) print(soup.find_all(name=re.compile("^b"))) # find_all 查找所有符合要求的 可以按照屬性查找,比如這里的id,class # 因?yàn)閏lass是關(guān)鍵字,所以使用class_代替class print(soup.find_all(id='link2')) print(soup.find_all(class_='sister')) # select 查找所有符合要求的 支持選擇器 print(soup.select('title')) print(soup.select('.sister')) print(soup.select('#link1')) print(soup.select('p #link1')) print(soup.select('a[class="sister"]')) # 獲取內(nèi)容 print(soup.select('title')[0].get_text())

例二:
>>> from bs4 import BeautifulSoup
>>> import requests
>>> r = requests.get("http://python123.io/ws/demo.html")
>>> demo = r.text
>>> demo
'<html><head><title>This is a python demo page</title></head>\r\n<body>\r\n<p class="title"><b>The demo python introduces several python courses.</b></p>\r\n<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:\r\n<a  class="py1" id="link1">Basic Python</a> and <a  class="py2" id="link2">Advanced Python</a>.</p>\r\n</body></html>'
>>> soup = BeautifulSoup(demo,"html.parser")
>>> soup.title #獲取標(biāo)題
<title>This is a python demo page</title>
>>> soup.a #獲取a標(biāo)簽
<a class="py1"  id="link1">Basic Python</a>
>>> soup.title.string
'This is a python demo page'
>>> soup.prettify() #輸出html標(biāo)準(zhǔn)格式內(nèi)容
'<html>\n <head>\n <title>\n This is a python demo page\n </title>\n </head>\n <body>\n <p class="title">\n <b>\n The demo python introduces several python courses.\n </b>\n </p>\n <p class="course">\n Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:\n <a class="py1"  id="link1">\n Basic Python\n </a>\n and\n <a class="py2"  id="link2">\n Advanced Python\n </a>\n .\n </p>\n </body>\n</html>'
>>> soup.a.name #每個(gè)<tag>都有自己的名字,通過<tag>.name獲取
'a'
>>> soup.p.name
'p'
>>> tag = soup.a
>>> tag.attrs
{'href': 'http://www.icourse163.org/course/BIT-268001', 'class': ['py1'], 'id': 'link1'}
>>> tag.attrs['class']
['py1']
>>> tag.attrs['href']
'http://www.icourse163.org/course/BIT-268001'
>>> type(tag.attrs)
<class 'dict'>
>>> type(tag)
<class 'bs4.element.Tag'>

 五.更多數(shù)據(jù)提取的方式

5.1 XPath和lxml

  5.1.1 xml

         xml被用來傳輸和存儲(chǔ)數(shù)據(jù)。參考:https://www.runoob.com/xml/xml-tutorial.html

  5.1.2 xpath

        參考:https://www.runoob.com/xpath/xpath-tutorial.html

  5.1.3 lxml

        xml被設(shè)計(jì)用來傳輸和存儲(chǔ)數(shù)據(jù),HTML被設(shè)計(jì)用來顯示數(shù)據(jù)。這兩個(gè)都是樹形結(jié)構(gòu),可以先將HTML文件轉(zhuǎn)換成xml文檔,然后用xpath語法查找HTML節(jié)點(diǎn)或元素。這樣就用到了lxml模塊

# lxml安裝:
pip install lxml
# 使用
(1"""將字符串解析為HTML文檔"""

from lxml import etree

text='''
<div>
<ul>
<liclass="item-0"><ahref="link1.html">firstitem</a></li>
<liclass="item-1"><ahref="link2.html">seconditem</a></li>
<liclass="item-inactive"><ahref="link3.html">thirditem</a></li>
<liclass="item-1"><ahref="link4.html">fourthitem</a></li>
<liclass="item-0"><ahref="link5.html">fifthitem</a>
</ul>
</div>
'''

#利用etree.HTML,將字符串解析為HTML文檔
html=etree.HTML(text)

#按字符串序列化HTML文檔
result=etree.tostring(html).decode('utf-8')

print(result)

(2"""讀文件"""

from lxml import etree

# 讀取外部文件hello.html
html = etree.parse('./data/hello.html')
# pretty_print=True表示格式化,比如左對(duì)齊和換行
result = etree.tostring(html, pretty_print=True).decode('utf-8')

print(result)

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
python網(wǎng)絡(luò)爬蟲常用技術(shù)
Python 爬蟲介紹 | 菜鳥教程
python爬蟲系列(2)—— requests和BeautifulSoup
Python爬蟲入門保姆級(jí)教程!看完不會(huì)來找我
python3.4學(xué)習(xí)筆記(十七) 網(wǎng)絡(luò)爬蟲使用Beautifulsoup4抓取內(nèi)容
談一談|以實(shí)踐談爬蟲思路
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服