一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Python網(wǎng)絡(luò)爬蟲(chóng)(一)

 悅光陰 2022-02-21

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

1.1爬蟲(chóng)的定義

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

1.2爬蟲(chóng)的類型

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

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

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

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

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

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

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

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

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

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

二.爬蟲(chóng)開(kāi)發(fā)基礎(chǔ)

2.1 HTTP與HTTPS

       http是一個(gè)簡(jiǎn)單的請(qǐng)求-響應(yīng)協(xié)議,它通常運(yùn)行在TCP之上。它指定了客戶端可能發(fā)送給服務(wù)器什么樣的消息以及得到什么樣的響應(yīng)。客戶端是終端用戶,服務(wù)器端是網(wǎng)站。通常使用web瀏覽器,網(wǎng)絡(luò)爬蟲(chóng)或者其他工具,客戶端會(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)行一次握手,在握手過(guò)程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息。

2.2 請(qǐng)求頭

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

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

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

    (2)Accept-Charset:編碼類型

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

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

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

    (6)Referer:請(qǐng)求來(lái)自于那個(gè)頁(yè)面的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ú)立于編程語(yǔ)言的文本格式來(lái)存儲(chǔ)和表示數(shù)據(jù)。簡(jiǎn)潔和清晰的層次結(jié)構(gòu)使得 JSON 成為理想的數(shù)據(jù)交換語(yǔ)言。 易于人閱讀和編寫,同時(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í)編程語(yǔ)言。是一種解釋性腳本語(yǔ)言(代碼不進(jìn)行預(yù)編譯), 主要用來(lái)向HTML標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言下的一個(gè)應(yīng)用)頁(yè)面添加交互行為。

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

2.6 Ajax

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

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

(1)打開(kāi)菜單-tools-fidder options-https。

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

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

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

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

(1)配置fiddler遠(yuǎn)程連接模式。打開(kāi)菜單欄: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)到證書(shū)下載頁(yè)面,點(diǎn)擊下載fiddlerroot certificate.

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

四.開(kāi)始爬蟲(chóng)

4.1 urllib模塊

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

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

 urllib的方法及使用:

1 urllib.urlopen(url[, data[, proxies[,timeout[, context]]]]) 
功能說(shuō)明:urllib是用于訪問(wèn)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)
功能說(shuō)明:聲明一個(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:///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打開(kāi)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表示訪問(wèn)成功,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:///get')  # 發(fā)送get請(qǐng)求
print(r.text)

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

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

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

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

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

r = requests.options('https:///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)證書(shū)驗(yàn)證
import requests
url = 'https://kyfw.12306.cn/otn/leftTicket/init'
# 關(guān)閉證書(shū)驗(yàn)證
r = requests.get(url, verify=False)
print(r.status_code)
# 開(kāi)啟證書(shū)驗(yàn)證
# r = requests.get(url, verify=True)
# 設(shè)置證書(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ò)問(wèn)題,則請(qǐng)求將引發(fā)connectionerror異常。

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

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

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

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

4.3 re模塊

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

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

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

4.3.1 模塊內(nèi)容

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

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

"""match方法"""

import re

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

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ù)說(shuō)明:
· pattern:匹配的正則表達(dá)式
· string:要匹配的字符串
· flags:標(biāo)志位,用于控制正則表達(dá)式的匹配方式,如是否區(qū)分大小寫,是否多行匹配等。
flags參數(shù)可選值:
· re.I: 忽略大小寫(括號(hào)內(nèi)是完整寫法,下同)
· re.M: 多行模式,改變'^''$'的行為(參見(jiàn)上圖)
· 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的開(kāi)始位置匹配,search()會(huì)掃描整個(gè)string查找匹配,match()只有在0位置匹配成功的話才有返回,如果不是開(kāi)始位置匹配成功的話,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è)順序訪問(wèn)每一個(gè)匹配結(jié)果(Match對(duì)象)的迭代器。

"""finditer方法"""

import re

#返回一個(gè)迭代器,可以循環(huán)訪問(wè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è)國(guó)外電話號(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ù)說(shuō)明:
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éi)有匹配
m = pattern.match('one12twothree34four')
print(m)
# 從'e'的位置開(kāi)始匹配,沒(méi)有匹配
m = pattern.match('one12twothree34four', 2, 10)
print(m)
# 從'1'的位置開(kāi)始匹配,正好匹配,返回一個(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)頁(yè)解析庫(kù),可以從 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庫(kù)解析器

解析器 使用方法 條件
bs4的HTML解析器 BeautifulSoup(html,'html.parser') 安裝bs4庫(kù)
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 href="http:///elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http:///lacie" class="sister" id="link2">Lacie</a> and
<a href="http:///tillie" 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 href="http:///elsie" class="sister" id="link1"><!-- Elsie --></a>, <a href="http:///lacie" class="sister" id="link2">Lacie</a> and <a href="http:///tillie" 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:///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>都有自己的名字,通過(guò)<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被用來(lái)傳輸和存儲(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ì)用來(lái)傳輸和存儲(chǔ)數(shù)據(jù),HTML被設(shè)計(jì)用來(lái)顯示數(shù)據(jù)。這兩個(gè)都是樹(shù)形結(jié)構(gòu),可以先將HTML文件轉(zhuǎn)換成xml文檔,然后用xpath語(yǔ)法查找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)

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    日韩一区二区三区有码| 日本精品免费在线观看| 国产福利一区二区三区四区| 偷拍美女洗澡免费视频| 好吊日视频这里都是精品| 国产欧美一区二区另类精品| 欧美日不卡无在线一区| 日本一区二区三区久久娇喘| 久久福利视频这里有精品| 都市激情小说在线一区二区三区| 国产一区欧美一区日韩一区| 欧美中文字幕日韩精品| 性感少妇无套内射在线视频| 国产精品欧美日韩中文字幕| 欧美日本亚欧在线观看| 久久精品国产熟女精品| 午夜资源在线观看免费高清| 日韩免费国产91在线| 在线观看视频国产你懂的| 欧美韩日在线观看一区| 国产精品亚洲精品亚洲| 国产欧洲亚洲日产一区二区| 欧美丰满大屁股一区二区三区| 夜夜躁狠狠躁日日躁视频黑人| 日韩人妻免费视频一专区| 老司机亚洲精品一区二区| 日韩精品一区二区三区四区| 99久免费精品视频在线观| 午夜国产精品福利在线观看| 亚洲中文字幕视频在线播放| 亚洲淫片一区二区三区| 日本淫片一区二区三区| 久久婷婷综合色拍亚洲| 国产精品福利一二三区| 国产午夜免费在线视频| 日本加勒比在线播放一区| 日本熟妇五十一区二区三区| 亚洲精品一区二区三区免| 久久综合狠狠综合久久综合| 欧美日韩中国性生活视频| 麻豆果冻传媒一二三区|