介概述:
使用特定引擎解析網頁里面得數據,根據規則提取入庫
常見的技術:
正則、xpath、pyquery、Beautiful Soup4
開源測試工具 http://tool.oschina.net/regex/
官網:https://docs.python.org/zh-cn/3/library/re.html
. | 匹配除 "\n" 之外的任何單個字符。要匹配包括 '\n' 在內的任何字符,請使用象 '[.\n]' 的模式。 |
\d | 匹配一個數字字符。等價于 [0-9]。 |
\D | 匹配一個非數字字符。等價于 [^0-9]。 |
\s | 匹配任何空白字符,包括空格、制表符、換頁符等等。等價于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等價于 [^ \f\n\r\t\v]。 |
\w | 匹配包括下劃線的任何單詞字符。等價于'[A-Za-z0-9_]'。 |
\W | 匹配任何非單詞字符。等價于 '[^A-Za-z0-9_]'。 |
1、match
用法: 提取關鍵參數 比如 token sign 后端返回得簽名信息 算法
import re
content='Hello 123 456 welcome to world'
print(len(content))
result=re.match('^Hello\s\d\d\d\s\d{3}\s\w{7}', content)
print(result)
print(result.group())
print(result.span())
方法 | 說明 |
group(num=0) | 匹配的整個表達式的字符串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組 |
groups() | 返回一個包含所有小組字符串的元組,從 1 到 所含的小組號 |
1)匹配數字
import re
content='Hello 123456 welcome to world'
result=re.match('^Hello\s(\d+)\swelcome', content)
print(result)
print(result.group(1))
print(result.span())
2)通用匹配
import re
content='Hello 123 456 welcome to world'
# 匹配所有數據
result=re.match('^Hello.*ng$', content)
# 匹配某某開始到某某結束
result=re.match('^Hello(.*)ng$', content).group(1)
print(result)
print(result.group())
print(result.span())
3)貪婪和非貪婪
import re
content1='http://xxxxx.com/yyds/baidu'
result2=re.match('http.*com/(.*?)s', content1)
result2=re.match('http.*?com/(.*)s', content1)
print('result1', result1.group())
print('result2', result2.group())
4)修飾符
re.I | 使匹配對大小寫不敏感 |
re.L | 做本地化識別(locale-aware)匹配 |
re.M | 多行匹配,影響 ^ 和 $ |
re.S | 使 . 匹配包括換行在內的所有字符 |
re.U | 根據Unicode字符集解析字符。這個標志影響 \w, \W, \b, \B. |
re.X | 該標志通過給予你更靈活的格式以便你將正則表達式寫得更易于理解。 |
import re
# 這個修飾符的作用是匹配包括換行符在內的所有字符。
content='''Hello 1234567 World_This
is a Regex Demo
'''
result=re.match('^He.*?(\d+).*?Demo$', content)
result=re.match('^He.*?(\d+).*?Demo$', content,re.S)
print(result.group())
2、search
用法: 提取數據
re模塊中的search函數對整個字符串進行掃描并返回第一個匹配的結果。從左到右進行掃描
1)匹配數據
text='人生苦短,我用pythons'
res1=re.search('python',text)
data='result:{"name":"王五","age":"20"}'
res3=re.search("{.*?}",data)
2)正則提取案例
地址:https://finance.ifeng.com/c/8HzIujEasuH
url='https://finance.ifeng.com/c/8HzIujEasuH'
from utils.base import Spider
res=Spider().fetch(url)
import re
# 不帶符號
# text=re.findall('var allData={(.*)};',res.text)
# 帶符號
# text=re.findall('var allData\s=\s(.*);',res.text)
3)匹配中文
[\u4e00-\u9fa5]
s='大家晚上好asdasdsad'
aa=re.findall('[\u4e00-\u9fa5]+',s)
環境安裝
pip install pyquery
利用它,我們可以直接解析 DOM 節點的結構,并通過 DOM 節點的一些屬性快速進行內容提取。
html='''
<div id="cont">
<ul class="slist">
<li class="item-0">web開發</li>
<li class="item-1"><a href="link2.html">爬蟲開發</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">數據分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度學習</a></li>
<li class="item-0"><a href="link5.html">機器學習</a></li>
</ul>
</div>
'''
1、實例演示
from pyquery import PyQuery as pq
doc=pq(html)
print(doc('li'))
2、css選擇器
doc=pq(html)
print(doc('#cont .slist li'))
print(type(doc('#cont .slist li')))
3、提取內容
for item in doc('#cont .slist li').items():
print(item.text())
4、子節點
from pyquery import PyQuery as pq
doc=pq(html)
items=doc('.slist')
print(type(items))
print(items) # 提取節點所有內容
lis=items.find('li') # 獲取符合條件的li標簽
print(type(lis))
print(lis)
5、 屬性獲取
from pyquery import PyQuery as pq
doc=pq(html)
a=doc('.item-0.active a')
print(a, type(a))
print(a.attr('href'))
6、遍歷提取
doc=pq(html)
a=doc('a')
for s in a.items():
print(s.attr('href')) # 屬性獲取
print(s.text()) # 值獲取
插件下載:https://chrome.zzzmh.cn/index#/search
XPath 的選擇功能十分強大,它提供了非常簡潔明了的路徑選擇表達式。另外,它還提供了超過 100 個內建函數,用于字符串、數值、時間的匹配以及節點、序列的處理等。幾乎所有我們想要定位的節點,都可以用 XPath 來選擇。
官網:https://www.w3.org/TR/xpath/
安裝xpath解析庫:
pip install lxml
表 3-1 XPath 常用規則
表 達 式 | 描 述 |
nodename | 選取此節點的所有子節點 |
/ | 從當前節點選取直接子節點 |
// | 從當前節點選取子孫節點 |
. | 選取當前節點 |
.. | 選取當前節點的父節點 |
@ | 選取屬性 |
案例演示
text='''
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a>
</ul>
</div>
'''
1、解析
from lxml import etree
html=etree.HTML(text)
result=etree.tostring(html)
print(result.decode('utf-8'))
2、節點操作
我們一般會用 // 開頭的 XPath 規則來選取所有符合要求的節點。這里以前面的 HTML 文本為例,如果要選取所有節點,可以這樣實現:
這里使用 * 代表匹配所有節點,也就是整個 HTML 文本中的所有節點都會被獲取。可以看到,返回形式是一個列表,每個元素是 Element 類型,其后跟了節點的名稱,如 html、body、div、ul、li、a 等,所有節點都包含在列表中了。
result=html.xpath('//*')
3、子節點
result=html.xpath('//li/a')
result=html.xpath('//li/a/text()') # 提取數據
result=html.xpath('//li/a/@href') # 屬性值
4、指定節點獲取
result=html.xpath('//li[@class="item-0"]/a/text()')
print(result)
# ['first item', 'fifth item']
5、匹配翻頁元素
# 最后一個
//div[@class="page"]/a[last()-1]
# 下一頁
//div[@class="page"]/a[text()="下一頁>"]/@href
6、案例演示
? 說明:提取當前網站的首頁標題信息,要求使用xpath解析器
from lxml import etree
url1='https://www.icswb.com/channel-list-channel-162.html'
res4=Spider().fetch(url=url1)
html=etree.HTML(res4.text)
li=html.xpath('//ul[@id="NewsListContainer"]/li')
for i in li:
href=i.xpath('./h3/a/text()')
print(href)
簡單來說,BeautifulSoup 就是 Python 的一個 HTML 或 XML 的解析庫,我們可以用它來方便地從網頁中提取數據,官方的解釋如下:
BeautifulSoup 提供一些簡單的、Python 式的函數用來處理導航、搜索、修改分析樹等功能。它是一個工具箱,通過解析文檔為用戶提供需要抓取的數據,因為簡單,所以不需要多少代碼就可以寫出一個完整的應用程序。
BeautifulSoup 自動將輸入文檔轉換為 Unicode 編碼,輸出文檔轉換為 utf-8 編碼。你不需要考慮編碼方式,除非文檔沒有指定一個編碼方式,這時你僅僅需要說明一下原始編碼方式就可以了。
BeautifulSoup 已成為和 lxml、html5lib 一樣出色的 Python 解釋器,為用戶靈活地提供不同的解析策略或強勁的速度。
表 4-1 Beautiful Soup 支持的解析器
解析器 | 使用方法 | 優勢 | 劣勢 |
Python 標準庫 | BeautifulSoup(markup, "html.parser") | Python 的內置標準庫、執行速度適中 、文檔容錯能力強 | Python 2.7.3 or 3.2.2) 前的版本中文容錯能力差 |
LXML HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快、文檔容錯能力強 | 需要安裝 C 語言庫 |
LXML XML 解析器 | BeautifulSoup(markup, "xml") | 速度快、唯一支持 XML 的解析器 | 需要安裝 C 語言庫 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容錯性、以瀏覽器的方式解析文檔、生成 HTML5 格式的文檔 | 速度慢、不依賴外部擴展 |
通過以上對比可以看出,lxml 解析器有解析 HTML 和 XML 的功能,而且速度快,容錯能力強,所以推薦
1、安裝
pip install beautifulsoup4
2、demo
from bs4 import BeautifulSoup
# 2個參數 html 文本 解析引擎
soup=BeautifulSoup('<p>Hello world</p>', 'lxml')
print(soup.p.string)
3、節點選擇器
直接調用節點的名稱就可以選擇節點元素,再調用 string 屬性就可以得到節點內的文本了,這種選擇方式速度非常快。如果單個節點結構層次非常清晰,可以選用這種方式來解析。
下面再用一個例子詳細說明選擇元素的方法:
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://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup=BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
print(soup.p)
4、獲取屬性
每個節點可能有多個屬性,比如 id 和 class 等,選擇這個節點元素后,可以調用 attrs 獲取所有屬性:
print(soup.p.attrs)
print(soup.p.attrs['name'])
5、嵌套選擇
html="""
<html><head><title>The Dormouse's story</title></head>
<body>
"""
from bs4 import BeautifulSoup
soup=BeautifulSoup(html, 'lxml')
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)
6、select(根據選擇器選取指定內容)
標簽選擇器(a),類選擇器(.dudu),id選擇器(#lala),組合選擇器(a, .dudu, #lala, .meme),層級選擇器(div.dudu#lala.meme.xixi 表示下面好多級和 div>p>a>.lala 只能是下面一級 ),偽類選擇器(不常用),屬性選擇器 (input[name=‘lala’])
1)樣例
htmls="""
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<p class="story">
Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1" title="xl">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
and
<a href="http://example.com/tillie" class="sister" id="link3" rel="noopener noreferrer ">Tillie</a>
and they lived at the bottom of a well.
</p>
<p class="story">...</p>
"""
2)層級選擇器
soup.select('.story > a > span')[0].text
3)id選擇器
print(soup.select('#link1'))
4)提取屬性
soup.select('#link1')[0].attrs['href']
5)屬性選擇器
print(soup.select("input[type='password']"))
6)提取實際數據
Web 開發中,解析 HTML 是一個常見的任務,特別是當我們需要從網頁中提取數據或操作 DOM 時。掌握 Node.js 中解析 HTML 的各種方式,可以大大提高我們提取和處理網頁數據的效率。本文將介紹如何在 Node.js 中解析 HTML。
HTML 解析是指將 HTML 文本轉換為可操作的數據結構,通常是 DOM(文檔對象模型)。DOM 是一個樹狀結構,表示了網頁的結構和內容,允許我們使用 JavaScript 操作和修改網頁。
以下是在 Node.js 中常用的幾種 HTML 解析方法:
1.Cheerio:Cheerio 是一個類似于 jQuery 的庫,它可以在服務器端使用 CSS 選擇器來解析 HTML 并操作 DOM。它適用于解析靜態 HTML 頁面。
2.jsdom:jsdom 是一個在 Node.js 中模擬 DOM 環境的庫。它能夠解析和操作 HTML,同時還支持模擬瀏覽器環境中的許多特性,如事件處理和異步請求。
3.htmlparser2:htmlparser2 是一個快速的 HTML 解析器,它能夠將 HTML 文檔解析成 DOM 節點流。它通常用于處理大型 HTML 文檔或流式數據。
以下是一個使用 Cheerio 解析 HTML 的實際案例,其中包含基本的路由與請求處理。確保你的開發環境中已經安裝了 Node.js 和 npm。
1、首先,創建一個新的文件夾,并在該文件夾中運行以下命令初始化項目:
npm init -y
2、安裝所需的依賴庫:
npm install express cheerio axios
3、創建一個名為 index.js 的文件,然后編寫以下代碼:
const express=require('express');
const axios=require('axios');
const cheerio=require('cheerio'); // 引入 cheerio 庫,用于解析 HTML
const app=express();
const PORT=3000;
app.get('/', async (req, res)=> {
try {
// 使用 Axios 發起 GET 請求獲取網頁的 HTML 內容
const response=await axios.get('https://apifox.com/blog/mock-manual/'); // 替換為你想要解析的網頁 URL
const html=response.data; // 獲取響應中的 HTML 內容
const $=cheerio.load(html); // 將 HTML 文本傳遞給 cheerio,創建一個類似于 jQuery 的對象
// 使用 cheerio 對象的選擇器來獲取網頁標題,并提取文本內容
const title=$('title').text();
res.send(`Title: ${title}`); // 將標題作為響應發送給客戶端
} catch (error) {
console.error(error);
res.status(500).send('An error occurred'); // 發生錯誤時發送錯誤響應
}
});
app.listen(PORT, ()=> {
console.log(`Server is running on port ${PORT}`); // 啟動服務器并監聽指定端口
});
在上述代碼中,注釋解釋了每個關鍵步驟的作用:
以 Apifox 為例,Apifox=Postman + Swagger + Mock + JMeter,Apifox 支持調試 http(s)、WebSocket、Socket、gRPC、Dubbo 等協議的接口,并且集成了 IDEA 插件。在后端人員寫完服務接口時,測試階段可以通過 Apifox 來校驗接口的正確性,圖形化界面極大的方便了項目的上線效率。
在本文的例子中,就可以通過 Apifox 來測試接口。新建一個項目后,在項目中選擇 “調試模式” ,填寫請求地址后即可快速發送請求,并獲得響應結果,上文的實踐案例如圖所示:
Node.js 提供了多種方法來解析 HTML,包括 Cheerio、jsdom 和 htmlparser2。選擇適合你需求的庫,可以輕松地操作和提取網頁內容。
知識擴展:
參考鏈接:
TML全局屬性是所有HTML元素共有的屬性。它們可以應用于所有元素,盡管它們可能對某些元素沒有影響。
HTML元素可以設置屬性
屬性可以在元素中添加附加信息
屬性一般描述于開始標簽
屬性總是以名稱/值對的形式出現,比如:name="value"。
屬性和屬性值對大小寫不敏感。不過,萬維網聯盟在其HTML4推薦標準中推薦小寫的屬性/屬性值。而新版本的(X)HTML要求使用小寫屬性。
class:為html元素定義一個或多個類名(classname)(類名從樣式文件引入)
id:定義元素的唯一id
style:規定元素的行內樣式(inlinestyle)
title:描述了元素的額外信息(作為工具條使用)
HTML使用標簽<a>來設置超文本鏈接。超鏈接可以是一個字,一個詞,或者一組詞,也可以是一幅圖像,您可以點擊這些內容來跳轉到新的文檔或者當前文檔中的某個部分。當您把鼠標指針移動到網頁中的某個鏈接上時,箭頭會變為一只小手。默認情況下,鏈接將以以下形式出現在瀏覽器中:
一個未訪問過的鏈接顯示為藍色字體并帶有下劃線。
訪問過的鏈接顯示為紫色并帶有下劃線。
點擊鏈接時,鏈接顯示為紅色并帶有下劃線。
如果為這些超鏈接設置了CSS樣式,展示樣式會根據CSS的設定而顯示。
在標簽<a>中使用了href屬性來描述鏈接的地址。
實例
<a href="https://www.kaikeba.com/">訪問開課吧</a>1復制代碼類型:[html]
上面這行代碼顯示為:訪問開課吧
點擊這個超鏈接會把用戶帶到開課吧的首頁。
使用target屬性,你可以定義被鏈接的文檔在何處顯示。
實例
<ahref="https://www.kaikeba.com/"target="_blank">訪問開課吧</a>
target="_blank":在新窗口中打開被鏈接文檔。
target="_self": 默認,在相同的框架中打開被鏈接文檔。
target="_parent":在父框架集中打開被鏈接文檔。
target="_top": 在整個窗口中打開被鏈接文檔。
target=framename:在指定的框架中打開被鏈接文檔。 1234567891011復制代碼類型:[html]
HTML圖像標簽及其屬性
在HTML中,圖像由<img>標簽定義。<img>是空標簽,意思是說,它只包含屬性,并且沒有閉合標簽。
要在頁面上顯示圖像,你需要使用源屬性(src)。src指"source"。源屬性的值是圖像的URL地址。
定義圖像的語法是:
<imgsrc="url"alt="some_text"> 1復制代碼類型:[html]
URL指存儲圖像的位置。
alt屬性用來為圖像定義一串預備的可替換的文本。在瀏覽器無法載入圖像時,替換文本屬性告訴讀者她們失去的信息。此時,瀏覽器將顯示這個替代性的文本而不是圖像。為頁面上的圖像都加上替換文本屬性是個好習慣,這樣有助于更好的顯示信息,并且對于那些使用純文本瀏覽器的人來說是非常有用的。
height(高度)與width(寬度)屬性用于設置圖像的高度與寬度。屬性值默認單位為像素。
<imgsrc="logo.jpg"alt="kaikeba"width="300"height="120"> 1復制代碼類型:[html]
提示:指定圖像的高度和寬度是一個很好的習慣。如果圖像指定了高度寬度,頁面加載時就會保留指定的尺寸。如果沒有指定圖片的大小,加載頁面時有可能會破壞HTML頁面的整體布局。
開課吧廣場-人才學習交流平臺
*請認真填寫需求信息,我們會在24小時內與您取得聯系。