主頁 > 資料庫 > Python網路爬蟲(一)

Python網路爬蟲(一)

2020-12-03 07:53:27 資料庫

一.理解網路爬蟲

1.1爬蟲的定義

       網路爬蟲又稱為網頁蜘蛛、網路機器人,網路爬蟲是一種按照一定的規則自動的抓取網路資訊的程式或者腳本,通俗的說,就是根據一定的演算法實作編程開發,主要通過URL實作資料的抓取和挖掘,

1.2爬蟲的型別

     根據系統結構和開發技術大致可分為4種型別:

     (1)通用網路爬蟲,又稱為全網爬蟲,常見的有百度,Google等,

     (2)聚焦網路爬蟲,又稱主題網路爬蟲,是選擇性的爬行根據需求的主題相關頁面的網路爬蟲,

     (3)增量式網路爬蟲,是指對已下載網頁采取增量式更新和只爬行新產生或者已經發生變化的網頁的爬蟲,它能夠在一定程度上保證所爬行的頁面盡可能是新的頁面,只會在需要的時候爬行新產生或發生更新的頁面,并不重新下載沒有發生變化的頁面,這類爬蟲在實際中不太普及,

     (4)深層網路爬蟲,是大部分內容不能通過靜態URL獲取的,隱藏在表單后的,只有用戶提交一些關鍵詞才能獲得的網路頁面,

        這四類大致又可以分為兩類,通用爬蟲和聚焦爬蟲,聚焦網路爬蟲,增量式網路爬蟲和深層網路爬蟲可歸為一類,因為他們是定向爬蟲資料,而通用爬蟲在網路上稱為搜索引擎,

        爬蟲的設計思路:

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

        (2)通過http請求來獲取對應的HTML頁面;

        (3)提取HTML的內容,若是有用的資料,就保存起來;若是繼續爬取的頁面,就重新指定第(2)步,

二.爬蟲開發基礎

2.1 HTTP與HTTPS

       http是一個簡單的請求-回應協議,它通常運行在TCP之上,它指定了客戶端可能發送給服務器什么樣的訊息以及得到什么樣的回應,客戶端是終端用戶,服務器端是網站,通常使用web瀏覽器,網路爬蟲或者其他工具,客戶端會發起一個到服務器上指定的http請求,這個客戶端就叫做用戶代理(User Agent),一旦收到請求,服務器會發回一個狀態行(如“http/1.1 200 OK”)和 回應的 訊息,其中訊息的內容可能是請求的檔案,錯誤訊息或者其他訊息,

       http協議傳輸的資料都是未加密的,因此使用http協議傳輸隱私資訊非常不安全,

       https協議傳輸的資料都是加密的,在傳輸資料之前需要客戶端與服務端之間進行一次握手,在握手程序中將確立雙方加密傳輸資料的密碼資訊,

2.2 請求頭

       請求頭描述客戶端向服務器發送請求時使用的協議型別,所使用的編碼以及發送內容的長度等,檢測請求頭是常見的反爬蟲策略,因為服務器會對請求頭做一次檢測來判斷此次請求是人為的還是非人為的,所以我們在每次發送請求時都添加上請求頭,

     請求頭的引數如下:

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

    (2)Accept-Charset:編碼型別

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

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

    (5)Host:請求的主機地址和埠

    (6)Referer:請求來自于那個頁面的URL

    (7)User-Agent:瀏覽器相關資訊

    (8)Cookie:瀏覽器暫存服務器發送的資訊

    (9)Connection:http請求版本的特點

   (10)Date:請求網站的時間

2.3 cookies

       它是指某些網站為了辯護用戶身份,進行session跟蹤而存盤在用戶本地終端上的資料,一個cookies就是存盤在用戶主機瀏覽器 的文本檔案,

       服務器可以利用cookies包含的資訊判斷在http傳輸中的狀態,

2.4 JSON

      JSON(JavaScript Object Notation, JS 物件簡譜) 是一種輕量級的資料交換格式,它基于ECMAScript (歐洲計算機協會制定的js規范)的一個子集,采用完全獨立于編程語言的文本格式來存盤和表示資料,簡潔和清晰的層次結構使得 JSON 成為理想的資料交換語言, 易于人閱讀和撰寫,同時也易于機器決議和生成,并有效地提升網路傳輸效率,

例如:

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

2.5 JavaScript

       JavaScript(簡稱“JS”) 是一種具有函式優先的輕量級,解釋型或即時編譯型的高級編程語言,是一種解釋性腳本語言(代碼不進行預編譯), 主要用來向HTML(標準通用標記語言下的一個應用)頁面添加互動行為,

       JavaScript還能根據用戶觸發某些事件對用戶的操作進行加工處理,要在爬蟲實作一些功能,就要分析JS如何執行整個用戶登錄程序,

2.6 Ajax

        Ajax 不是一種新的編程語言,而是一種用于創建更好更快以及互動性更強的Web應用程式的技術,使用 JavaScript 向服務器提出請求并處理回應而不阻塞用戶核心物件XMLHttpRequest,通過這個物件,您的 JavaScript 可在不多載頁面的情況與 Web 服務器交換資料,即在不需要重繪頁面的情況下,就可以產生區域重繪的效果,         Ajax 在瀏覽器與 Web 服務器之間使用異步資料傳輸(HTTP 請求),這樣就可使網頁從服務器請求少量的資訊,而不是整個頁面,         判斷網頁資料是否使用ajax的方法:觸發事件之后,判斷網頁是否發生重繪狀態,若網頁沒有發生重繪,資料就自動生成,說明資料的加載是通過ajax生成并渲染到網頁上的,反之,數據是通過服務器后臺生成并加載的,

三.Fiddler抓包工具

       Fiddler是一個http協議除錯代理工具,它能夠記錄并檢查所有你的電腦和互聯網之間的http通訊,設定斷點,查看所有的“進出”Fiddler的資料(指cookie,html,js,css等檔案),

3.1 fiddler安裝配置

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

       配置fiddler,使其能夠抓取https請求資訊:

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

(2)勾選https中的選項,然后點擊actions-trust root certificate,完成整數驗證,

3.2 fiddler抓取手機應用

    fiddler可通過同一無線網路實作對手機應用的抓包,手機抓包主要通過遠程連接實作手機和fiddler通信,

    實作fiddler抓取手機應用的步驟如下:

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

(2)在手機端進行引數配置,要連接在同一個IP地址上(cmd中輸入ipconfig查看IP地址)

(3)在手機瀏覽器中輸入電腦IP地址和fiddler埠,點擊確認后跳轉到證書下載頁面,點擊下載fiddlerroot certificate.

(4)證書檔案以cer為后綴名,完成證書安裝后,進入手機當前連接WiFi詳情,設定代理IP,主機名為電腦IP地址,埠為fiddler配置的埠,

四.開始爬蟲

4.1 urllib模塊

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

1 urllib.request:用來打開和讀取URL,
2 urllib.error:包含了urllib.request產生的例外,
3 urllib.parse:用來決議和處理URL,
4 urllib.robotparse:用于決議robots.txt檔案,

 urllib的方法及使用:

1 urllib.urlopen(url[, data[, proxies[,timeout[, context]]]]) 
功能說明:urllib是用于訪問URL的唯一方法  
引數解釋:
url :一個完整的遠程資源路徑,一般是一個網站,
data:默認值為none,若引數data為none,則代表請求方式為get,反之請求方式為post,發送post請求,引數data以字典形式存盤資料,并將引數data由字典型別轉換成位元組型別才能完成post請求, proxies : 設定代理 timeout:超時設定 context:描述各種SSL選項的實體,
2 urllib.request.Request(url,data=https://www.cnblogs.com/z-8888/p/none,headers={},method=none)
功能說明:宣告一個request物件,該物件可定義header等請求資訊
引數解釋:
headers:設定request請求頭資訊
method:設定請求方式,主要是get和post
"""urllib的使用"""
import
urllib.request # 向指定URL發送請求,獲取回應, response = urllib.request.urlopen('http://httpbin.org/anything') # 獲取回應內容 content = response.read().decode('utf-8') print(content) print(type(response)) # 回應碼 print(response.status) # 回應頭資訊 print(response.headers)
# 匯入urllib
import urllib.request
url = 'https://movie.douban.com/'
# 自定義請求頭
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'}
# 設定request的請求頭
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的基礎上做了封裝,具備urllib的全部功能,讓使用者更加方便的使用, 

       安裝:pip install requests

4.2.1 發出請求

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

1 requests.get(url, params=none, **kwargs)
2 requests.post(url, data=https://www.cnblogs.com/z-8888/p/none, json=none, **kwargs)

   requests提供如下方法獲取回應內容:

 1 r.status_code:回應狀態碼(200表示訪問成功,4**表示失敗)
 2 r.raw:原始回應體,使用r.raw.read()讀取
 3 r.content:位元組方式的回應體,需要進行解碼
 4 r.text:字串方式的回應體,會自動根據回應頭部的字符編碼進行解碼
 5 r.headers:以字典物件存盤服務器回應頭,若鍵不存在,則回傳none
 6 r.json():requests中內置的json解碼器
 7 r.raise_for_status():請求失敗(非200回應),拋出例外
 8 r.url:獲取請求鏈接
 9 r.cookies:獲取請求后的cookies
10 r.encoding:獲取編碼格式
"""使用requests發送請求和攜帶引數"""

import requests

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

# 發送post請求,并帶引數
r = requests.get('https://httpbin.org/get', params={'key1': 'value1', 'key2': 'value2'})
print(r.text)

# 發送post請求,并傳遞引數
r = requests.post('https://httpbin.org/post', data=https://www.cnblogs.com/z-8888/p/{'key': 'value'})
print(r.text)

# 其他HTTP請求型別:PUT,DELETE,HEAD和OPTIONS
r = requests.put('https://httpbin.org/put', data=https://www.cnblogs.com/z-8888/p/{'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 復雜的請求方式

(1)添加請求頭
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)證書驗證
import requests
url = 'https://kyfw.12306.cn/otn/leftTicket/init'
# 關閉證書驗證
r = requests.get(url, verify=False)
print(r.status_code)
# 開啟證書驗證
# r = requests.get(url, verify=True)
# 設定證書所在路徑
# r = requests.get(url, verify= '/path/to/certfile')
4)超時設定
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 錯誤和例外

   若出現網路問題,則請求將引發connectionerror例外,

   若http請求回傳不成功的狀態碼,則將會引發httperror例外,

   若請求超時,則會引起超時例外,

   若請求超過配置的最大重定向數,則會引發TooManyRedirects例外,

   請求顯示引發的所有例外都繼承自requests.exceptions.RequestException,

4.3 re模塊

       正則運算式是對字串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字串”,這個“規則字串”用來表達對字串的一種過濾邏輯,

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

       語法請參考:https://www.runoob.com/regexp/regexp-tutorial.html

4.3.1 模塊內容

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

       這個方法將會從string(我們要匹配的字串)的開頭開始,嘗試匹配pattern,一直向后匹配,如果遇到無法匹配的字符,立即回傳None,如果匹配未結束已經到達string的末尾,也會回傳None,兩個結果均表示匹配失敗,否則匹配pattern成功,同時匹配終止,不再對string向后匹配,

"""match方法"""

import re

# match在起始位置匹配
ret = re.match('www', 'www.example.com')
print(type(ret))
# 獲取匹配的內容
print(ret.group())
# 獲取匹配內容在原字串里的下標
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())
    # 獲取第一組的內容
    print("matchObj.group(1) : ", matchObj.group(1))
    print("matchObj.group(2) : ", matchObj.group(2))
else:
    print("No match!!")

 

引數說明:
? pattern:匹配的正則運算式
? string:要匹配的字串
? flags:標志位,用于控制正則運算式的匹配方式,如是否區分大小寫,是否多行匹配等,
flags引數可選值:
? re.I: 忽略大小寫(括號內是完整寫法,下同)
? re.M: 多行模式,改變'^''$'的行為(參見上圖)
? re.S: 點任意匹配模式,改變'.'的行為
? re.L: 使預定字符類 \w \W \b \B \s \S 取決于當前區域設定
? re.U: 使預定字符類 \w \W \b \B \s \S \d \D 取決于unicode定義的字符屬性
? re.X: 詳細模式,這個模式下正則運算式可以是多行,忽略空白字符,并可以加入注釋,

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

    search方法與match方法極其類似,區別在于match()函式只檢測re是不是在string的開始位置匹配,search()會掃描整個string查找匹配,match()只有在0位置匹配成功的話才有回傳,如果不是開始位置匹配成功的話,match()就回傳None,同樣,search方法的回傳物件同樣match()回傳物件的方法和屬性,

"""search方法"""

import re

# search查找第一次出現
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

# 查找數字
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,回傳一個順序訪問每一個匹配結果(Match物件)的迭代器,

"""finditer方法"""

import re

#回傳一個迭代器,可以回圈訪問,每次獲取一個Match物件
it = re.finditer(r"\d+", "12a32bc43jf3")
for match in it:
    print(match.group())

 

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

    按照能夠匹配的子串將string分割后回傳串列,maxsplit用于指定最大分割次數,不指定將全部分割,

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

 

"""sub方法"""

import re

phone = "2004-959-559 # 這是一個國外電話號碼"

# 洗掉字串中的 Python注釋
num = re.sub(r'#.*$', "", phone)
print("電話號碼是: ", num)

# 洗掉非數字(-)的字串
num = re.sub(r'\D', "", phone)
print("電話號碼是 : ", num)


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


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

 

 

 

引數說明:
1
repl:用于替換的字串 2 string:要被替換的字串 3 count:替換的次數

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

    與sub()函式一致,回傳結果是一個元組,

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

    該函式用于編譯正則運算式生成一個正則運算式(pattern)物件,供match()和search()等函式使用,

"""compile方法"""


import re

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

 

 4.4BeautifulSoup4模塊

  4.4.1 簡介  

     Beautiful Soup,有了它我們可以很方便地提取出 HTML 或 XML 標簽中的內容,BeautifulSoup是一個高效的網頁決議庫,可以從 HTML 或 XML 檔案中提取資料,

beautifulsoup支持不同的決議器,比如,對HTML決議,對XML決議,對HTML5決議,一般情況下,我們用的比較多的是 lxml 決議器,

  4.4.2 安裝

1 pip install beautifulsoup4

使用時匯入:

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  name="dromouse"><b>The Dormouse's story</b></p>
<p >Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie"  id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie"  id="link2">Lacie</a> and
<a href="http://example.com/tillie"  id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p >...</p>
"""

# 創建BeautifulSoup物件決議html,并使用lxml作為xml決議器soup = BeautifulSoup(html, 'lxml')

# 格式化輸出soup物件的內容
print(soup.prettify())
例一:
"""
bs4實體測驗""" from bs4 import BeautifulSoup import re html = """ <html><head><title>The Dormouse's story</title></head> <body> <p name="dromouse"><b>The Dormouse's story</b></p> <p >Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a href="http://example.com/lacie" id="link2">Lacie</a> and <a href="http://example.com/tillie" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p >...</p> """ # 創建物件 soup = BeautifulSoup(html, 'lxml') # 獲取Tag物件 # 查找的是在所有內容中的第一個符合要求的標簽 print(soup.title) print(type(soup.title)) print(soup.p) # 標簽的名字 print(soup.p.name) # 標簽的屬性,可獲取,也可以設定 print(soup.p.attrs) print(soup.p.attrs['class']) # 文本 print(soup.p.string) # content屬性得到子節點,串列型別 print(soup.body.contents) # children屬性屬性得到子節點,可迭代物件 print(soup.body.children) # descendants屬性屬性得到子孫節點,可迭代物件 print(soup.body.descendants) # find_all 查找所有符合要求的 name是按照標簽名字查找 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 # 因為class是關鍵字,所以使用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[]')) # 獲取內容 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 ><b>The demo python introduces several python courses.</b></p>\r\n<p >Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:\r\n<a href="http://www.icourse163.org/course/BIT-268001"  id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001"  id="link2">Advanced Python</a>.</p>\r\n</body></html>'
>>> soup = BeautifulSoup(demo,"html.parser")
>>> soup.title #獲取標題
<title>This is a python demo page</title>
>>> soup.a #獲取a標簽
<a  href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>
>>> soup.title.string
'This is a python demo page'
>>> soup.prettify() #輸出html標準格式內容
'<html>\n <head>\n <title>\n This is a python demo page\n </title>\n </head>\n <body>\n <p >\n <b>\n The demo python introduces several python courses.\n </b>\n </p>\n <p >\n Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:\n <a  href="http://www.icourse163.org/course/BIT-268001" id="link1">\n Basic Python\n </a>\n and\n <a  href="http://www.icourse163.org/course/BIT-1001870001" id="link2">\n Advanced Python\n </a>\n .\n </p>\n </body>\n</html>'
>>> soup.a.name #每個<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'>

 五.更多資料提取的方式

5.1 XPath和lxml

  5.1.1 xml

         xml被用來傳輸和存盤資料,參考: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被設計用來傳輸和存盤資料,HTML被設計用來顯示資料,這兩個都是樹形結構,可以先將HTML檔案轉換成xml檔案,然后用xpath語法查找HTML節點或元素,這樣就用到了lxml模塊

# lxml安裝:
pip install lxml
# 使用
(1"""將字串決議為HTML檔案"""

from lxml import etree

text='''
<div>
<ul>
<li><ahref="https://www.cnblogs.com/z-8888/p/link1.html">firstitem</a></li>
<li><ahref="https://www.cnblogs.com/z-8888/p/link2.html">seconditem</a></li>
<li><ahref="https://www.cnblogs.com/z-8888/p/link3.html">thirditem</a></li>
<li><ahref="https://www.cnblogs.com/z-8888/p/link4.html">fourthitem</a></li>
<li><ahref="https://www.cnblogs.com/z-8888/p/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表示格式化,比如左對齊和換行
result = etree.tostring(html, pretty_print=True).decode('utf-8')

print(result)

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/228952.html

標籤:大數據

上一篇:Clickhouse 入門

下一篇:Mysql binlog備份資料及恢復資料,學會這個,我在也不怕刪庫跑路啦~

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more