“
感覺只要學(xué)過Python爬蟲的同學(xué)應(yīng)該都知道requests這個(gè)庫吧,它在我們的Python爬蟲任務(wù)中應(yīng)該是最常用的一個(gè)庫了!今天跟大家分享的這個(gè)模塊requests_html,他的作者和前者是同一人!這是一個(gè)解析HTML的庫,用起來和requests一樣方便,下面就來介紹一下它!
”
#!/usr/bin/env python3
# coding : utf-8
# Author : xiao qiang
# 微信公眾號 : xiaoqiangclub
# Software : PyCharm
# File : test.py
# Time : 2021/5/29 7:57
from requests_html import HTMLSession
if __name__ == '__main__':
url = 'https://wwww.baidu.com'
session = HTMLSession() # 獲取實(shí)例化session對象
r = session.get(url) # 這里的請求和requests的幾乎一樣!同樣可以根據(jù)需要添加headers等參數(shù)
#!/usr/bin/env python3
# coding : utf-8
# Author : xiao qiang
# 微信公眾號 : xiaoqiangclub
# Software : PyCharm
# File : test.py
# Time : 2021/5/29 7:57
from requests_html import HTMLSession
if __name__ == '__main__':
url = 'https://wwww.baidu.com'
session = HTMLSession() # 獲取實(shí)例化session對象
r = session.get(url) # 這里的請求和requests的幾乎一樣!同樣可以根據(jù)需要添加headers等參數(shù)
# 獲取html頁面
# html = r.content.decode() # requests方式
get_html = r.html.html # requests_html中的方法
print(get_html[:15], '...')
# 快速獲取鏈接
pprint(r.html.links) # 獲取html中的鏈接(href屬性)
pprint(r.html.absolute_links) # 會自動拼接url生成絕對鏈接
def xpath(self, selector: str, *, clean: bool = False, first: bool = False, _encoding: str = None) -> _XPath:
- selector,要用的 xpath選擇器;
- clean,布爾值,如果為True,會清除HTML中style和script標(biāo)簽;
- first,布爾值,如果為True,會返回第一個(gè)元素,否則會返回滿足條件的元素列表;
- _encoding,編碼格式。
pprint(r.html.xpath('//li[@class="hotsearch-item odd"]/a'))
pprint(r.html.xpath('//li[@class="hotsearch-item odd"]/a', first=True).text)
def find(self, selector: str = "*", *, containing: _Containing = None, clean: bool = False, first: bool = False, _encoding: str = None) -> _Find:
- selector,要用的CSS選擇器;
- clean,布爾值,如果為True,會清除HTML中style和script標(biāo)簽;
- containing,如果設(shè)置該屬性,只返回包含該屬性文本的標(biāo)簽;
- first,布爾值,如果為True,會返回第一個(gè)元素,否則會返回滿足條件的元素列表;
- _encoding,編碼格式。
pprint(r.html.find('a.mnav'))
pprint(r.html.find('a.mnav', first=True).text)
pprint(r.html.find('a.mnav')[0].text)
pprint(r.html.find('a.mnav')[0].attrs)
pprint(r.html.find('a.mnav')[0].html)
def search(self, template: str) -> Result:
# 只有一個(gè)參數(shù)
template: 就是要檢索的內(nèi)容,這里使用英文狀態(tài)的 {} 來獲取內(nèi)容,有點(diǎn)類似正則里面的 ()
ret = r.html.find('a.mnav')[0].search('新{}')
pprint(ret)
pprint(type(ret))
pprint(ret[0])
ret = r.html.find('a.mnav')[0].search_all('新{}')
pprint(ret)
pprint(type(ret))
pprint(ret[0][0])
ret = r.html.search_all('百度{}')
pprint(ret)
pprint(type(ret))
pprint(ret[0][0])
search補(bǔ)充
>>> from requests_html import HTML
>>> doc = """<a href='https://www.baidu.com'>"""
>>> html = HTML(html=doc)
>>> html.links
{'https://www.baidu.com'}
# 和上面一段代碼接起來
>>> script = """
() => {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio,
}
}
"""
>>> val = html.render(script=script, reload=False) # render()方法 后面會講
>>> print(val)
{'width': 800, 'height': 600, 'deviceScaleFactor': 1}
>>> print(html.html)
<html><head></head><body><a href="https://www.baidu.com"></a></body></html>
>>> r = session.get('http://python-requests.org/')
>>> r.html.render()
[W:pyppeteer.chromium_downloader] start chromium download.
Download may take a few minutes.
[W:pyppeteer.chromium_downloader] chromium download done.
[W:pyppeteer.chromium_downloader] chromium extracted to: C:\Users\xxxx\.pyppeteer\local-chromium\571375
>>> r.html.search('Python 2 will retire in only {months} months!')['months']
'<time>25</time>'
def render(self, retries: int = 8, script: str = None, wait: float = 0.2, scrolldown=False, sleep: int = 0, reload: bool = True, timeout: Union[float, int] = 8.0, keep_page: bool = False):
- retries: 加載頁面失敗的次數(shù)
- script: 頁面上需要執(zhí)行的JS腳本(可選)
- wait: 加載頁面前等待的時(shí)間(秒),防止超時(shí)(可選)
- scrolldown: 頁面向下滾動的次數(shù)(整數(shù))
- sleep: 在頁面初次渲染之后的等待時(shí)間
- reload: 如果為False,那么頁面不會從瀏覽器中加載,而是從內(nèi)存中加載,只有設(shè)置為True才會在瀏覽器中渲染JS
- keep_page: 如果為True,允許您使用 r.html.page 訪問瀏覽器頁面
def next(self, fetch: bool = False, next_symbol: _NextSymbol = DEFAULT_NEXT_SYMBOL) -> _Next:
fetch: 一個(gè)布爾型參數(shù),默認(rèn)為False:直接返回下一頁的 url地址;
如果設(shè)置為True:則直接返回下一頁的 HTML對象
DEFAULT_NEXT_SYMBOL = ['next', 'more', 'older']
# next()方法
def next(self, fetch: bool = False, next_symbol: _NextSymbol = DEFAULT_NEXT_SYMBOL) -> _Next:
"""Attempts to find the next page, if there is one. If ``fetch``
is ``True`` (default), returns :class:`HTML <HTML>` object of
next page. If ``fetch`` is ``False``, simply returns the next URL.
"""
def get_next():
candidates = self.find('a', containing=next_symbol) # 尋找 包含字段'next', 'more', 'older' 的a標(biāo)簽
def __init__(self, loop=None, workers=None, mock_browser: bool = True, *args, **kwargs):
loop: 使用的Asyncio循環(huán)。
workers: 用于執(zhí)行異步調(diào)用的線程數(shù)量。如果不傳遞,它將默認(rèn)為電腦處理器數(shù)量乘以5
>>> async def get_pyclock():
... r = await asession.get('https://pythonclock.org/')
... await r.html.arender()
... return r
...
>>> results = asession.run(get_pyclock, get_pyclock, get_pyclock) # 這里作者將同一個(gè)頁面使用異步方式進(jìn)行了3次渲染,但是實(shí)際上使用的時(shí)間并不是平時(shí)的3倍!可能只是比平時(shí)渲染一個(gè)頁面多花了一點(diǎn)時(shí)間而已!這就是異步的好處!
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Author : xiao qiang
# @WeChat : xiaoqiangclub
# @Software : PyCharm
# @File : test002.py
# @Time : 2021/5/30 19:48
from requests_html import AsyncHTMLSession
aSession = AsyncHTMLSession()
async def test(tt, yy):
r = await aSession.get('https://www.baidu.com/')
await r.html.arender()
print('-{}-{}-'.format(tt, yy))
return r
ret1 = aSession.run(lambda: test('1', 'a'))
ret2 = aSession.run(lambda: test('2', 'b'))
ret3 = aSession.run(lambda: test('3', 'c'))
print(ret1)
print(ret2)
print(ret3)
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Author : xiao qiang
# @WeChat : xiaoqiangclub
# @Software : PyCharm
# @File : test002.py
# @Time : 2021/5/30 19:48
from requests_html import AsyncHTMLSession
aSession = AsyncHTMLSession()
async def test(tt, yy):
r = await aSession.get('https://www.baidu.com/')
await r.html.arender()
print('-{}-{}-'.format(tt, yy))
return r
# ret1 = aSession.run(lambda: test('1', 'a'))
# ret2 = aSession.run(lambda: test('2', 'b'))
# ret3 = aSession.run(lambda: test('3', 'c'))
# print(ret1)
# print(ret2)
# print(ret3)
#
test_dict = {
'1': 'a',
'2': 'b',
'3': 'c'
}
tasks = [lambda i=i, y=y: test(i, y) for i, y in
test_dict.items()] # lambda傳參誤區(qū)參考文章:https://www.jianshu.com/p/58ebd1618556
ret = aSession.run(*tasks) # 注意前面有個(gè) *,不可少!# 參考文章:https://www.jianshu.com/p/58ebd1618556
print(ret)
>>> from requests_html import AsyncHTMLSession
>>> asession = AsyncHTMLSession()
>>> async def get_pythonorg():
... r = await asession.get('https://python.org/')
... return r
...
>>> async def get_reddit():
... r = await asession.get('https://reddit.com/')
... return r
...
>>> async def get_google():
... r = await asession.get('https://google.com/')
... return r
...
>>> results = asession.run(get_pythonorg, get_reddit, get_google)
>>> results # check the requests all returned a 200 (success) code
[<Response [200]>, <Response [200]>, <Response [200]>]
>>> # Each item in the results list is a response object and can be interacted with as such
>>> for result in results:
... print(result.html.url)
...
https://www.python.org/
https://www.google.com/
https://www.reddit.com/
from requests_html import HTMLSession, HTML, AsyncHTMLSession
from pprint import pprint
class DouBanTest:
def __init__(self):
self.start_url = 'https://movie.douban.com/chart' # 豆瓣電影排行榜url
self.js_url = 'https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0'
self.session = HTMLSession() # 實(shí)例化session
self.aSession = AsyncHTMLSession() # 實(shí)例化異步session
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'
}
def get_response(self, url):
"""獲取響應(yīng),并返回requests_html中的HTML對象"""
r = self.session.get(url, headers=self.headers)
# print(r)
return r.html
# 快速獲取頁面中的url
def fast_get_urls(self):
"""快速獲取頁面中的url"""
html = self.get_response(self.start_url)
# HTML的 links屬性 可以快速獲取到頁面中 a標(biāo)簽中的href屬性
urls = html.links
# pprint(urls)
# HTML的 absolute_links屬性 可以快速獲取到頁面中 a標(biāo)簽中的href屬性,并返回絕對url地址
absolute_urls = html.absolute_links
pprint(absolute_urls)
# 清洗數(shù)據(jù)(提取數(shù)據(jù))
def get_data_by_xpath(self):
"""使用xpath獲取數(shù)據(jù)"""
html = self.get_response(self.start_url)
a_list = html.xpath('//table//div/a')
# pprint(a_list)
# 提取它的標(biāo)題和url
movies_info = dict()
for a in a_list:
title = a.text # 獲取標(biāo)題(文本)
# print(title)
movie_url = a.attrs.get('href') # 使用 attrs 來解析element元素,并獲得一個(gè)字典
# print(movie_url)
# print('-----')
movies_info[title] = movie_url
pprint(movies_info)
# 清洗數(shù)據(jù)(提取數(shù)據(jù))
def get_data_by_css(self):
"""使用css獲取數(shù)據(jù)"""
html = self.get_response(self.start_url)
a_list = html.find('tr[class="item"] div a') # 參考 css選擇器 語法
# pprint(a_list)
# 提取它的標(biāo)題和url
movies_info = dict()
for a in a_list:
title = a.text # 獲取標(biāo)題(文本)
# print(title)
movie_url = a.attrs.get('href') # 使用 attrs 來解析element元素,并獲得一個(gè)字典
# print(movie_url)
# print('-----')
movies_info[title] = movie_url
pprint(movies_info)
# 清洗數(shù)據(jù)(提取數(shù)據(jù))
def get_data_by_re(self):
"""使用css獲取數(shù)據(jù)"""
html = self.get_response(self.start_url)
# search() 獲取第一條匹配的數(shù)據(jù)
# first_url = html.search('a href="{}"') # 參數(shù)可以參考正則,獲取第一條匹配的數(shù)據(jù)
# pprint(first_url)
# search_all() 獲取所有滿足條件的數(shù)據(jù)列表
# url_list = html.search_all('a h{}f="{}"')
url_list = html.search_all('a h{title}f="{url}"') # 對取值方式進(jìn)行命名,返回一個(gè)列表
# pprint(url_list)
#
# 提取數(shù)據(jù)
for url in url_list:
print(url)
print(url['title']) # 使用 result[name] 進(jìn)行取值
print(url['url'])
# print(url[0])
# print(url[1])
print('----------')
# HTML類
def use_HTML(self):
"""使用HTML模塊處理文檔"""
html_str = '<a class="nbg" href="https://movie.douban.com/subject/3099221/" title="活死人軍團(tuán)">'
html = HTML(html=html_str)
# links
print(html.links)
# search()
print(html.search('href="{}"'))
# 加載JS頁面
def load_js(self):
html = self.get_response(self.js_url)
# 使用一個(gè) render()方法 來加載js(實(shí)際上使用這個(gè)pyppeteer)
# html.render(wait=3) # js加載
print(html.html)
async def send_requests_ues_async(self, url):
"""發(fā)送異步請求"""
"""獲取響應(yīng),并返回requests_html中的HTML對象"""
r = await self.aSession.get(url, headers=self.headers)
# print(r)
return r.html
def get_response_by_async(self):
url_list = [
'https://www.baidu.com',
'https://www.qq.com',
'https://www.163.com',
]
tasks = [lambda url=url: self.send_requests_ues_async(url) for url in url_list]
ret = self.aSession.run(*tasks) # 返回的是一個(gè)HTML對象列表
# print(ret)
# print(ret[0].html)
for html in ret:
print(html)
async def load_js_use_async(self, url):
"""異步加載js"""
html = await self.send_requests_ues_async(url)
# 異步加載js
await html.arender()
return html
def get_js_by_async(self):
# ret = self.aSession.run(self.load_js_use_async)
#
# print(ret[0].html)
url_list = [
'https://www.baidu.com',
'https://www.qq.com',
'https://www.163.com',
]
tasks = [lambda url=url: self.load_js_use_async(url) for url in url_list]
ret = self.aSession.run(*tasks) # 返回的是一個(gè)HTML對象列表
# print(ret)
# print(ret[0].html)
for html in ret:
print(html)
if __name__ == '__main__':
test = DouBanTest()
# test.get_data_by_xpath()
# test.get_data_by_css()
# test.fast_get_urls()
# test.get_data_by_re()
# test.use_HTML()
# test.load_js()
# test.get_response_by_async()
test.get_js_by_async()
【本文由 "XiaoqiangClub" 發(fā)布,2021年6月17日】
要使用的是wkhtmltopdf的Python封裝——pdfkit
安裝
1. Install python-pdfkit:
$ pip install pdfkit
2. Install wkhtmltopdf:
$ sudo apt-get install wkhtmltopdf
sudo yum intsall wkhtmltopdf
brew install Caskroom/cask/wkhtmltopdf
使用
一個(gè)簡單的例子:
import pdfkit
pdfkit.from_url('http://google.com', 'out.pdf')
pdfkit.from_file('test.html', 'out.pdf')
pdfkit.from_string('Hello!', 'out.pdf')
你也可以傳遞一個(gè)url或者文件名列表:
pdfkit.from_url(['google.com', 'yandex.ru', 'engadget.com'], 'out.pdf')
pdfkit.from_file(['file1.html', 'file2.html'], 'out.pdf')
也可以傳遞一個(gè)打開的文件:
with open('file.html') as f:
pdfkit.from_file(f, 'out.pdf')
如果你想對生成的PDF作進(jìn)一步處理, 你可以將其讀取到一個(gè)變量中:
# 設(shè)置輸出文件為False,將結(jié)果賦給一個(gè)變量
pdf = pdfkit.from_url('http://google.com', False)
你可以制定所有的 wkhtmltopdf 選項(xiàng) http://wkhtmltopdf.org/usage/wkhtmltopdf.txt. 你可以移除選項(xiàng)名字前面的 '--' .如果選項(xiàng)沒有值, 使用None, False or * 作為字典值:
options = {
'page-size': 'Letter',
'margin-top': '0.75in',
'margin-right': '0.75in',
'margin-bottom': '0.75in',
'margin-left': '0.75in',
'encoding': "UTF-8",
'no-outline': None
}
pdfkit.from_url('http://google.com', 'out.pdf', options=options)
默認(rèn)情況下, PDFKit 將會顯示所有的 wkhtmltopdf 輸出. 如果你不想看到這些信息,你需要傳遞一個(gè) quiet 選項(xiàng):
options = {
'quiet': ''
}
pdfkit.from_url('google.com', 'out.pdf', options=options)
由于wkhtmltopdf的命令語法 , TOC 和 Cover 選項(xiàng)必須分開指定:
toc = {
'xsl-style-sheet': 'toc.xsl'
}
cover = 'cover.html'
pdfkit.from_file('file.html', options=options, toc=toc, cover=cover)
當(dāng)你轉(zhuǎn)換文件、或字符串的時(shí)候,你可以通過css選項(xiàng)指定擴(kuò)展的 CSS 文件。
# 單個(gè) CSS 文件
css = 'example.css'
pdfkit.from_file('file.html', options=options, css=css)
# Multiple CSS files
css = ['example.css', 'example2.css']
pdfkit.from_file('file.html', options=options, css=css)
你也可以通過你的HTML中的meta tags傳遞任意選項(xiàng):
body = """
<html>
<head>
<meta name="pdfkit-page-size" content="Legal"/>
<meta name="pdfkit-orientation" content="Landscape"/>
</head>
Hello World!
</html>
"""
pdfkit.from_string(body, 'out.pdf') #with --page-size=Legal and --orientation=Landscape
配置
每個(gè)API調(diào)用都有一個(gè)可選的參數(shù)。這應(yīng)該是pdfkit.configuration()API 調(diào)用的一個(gè)實(shí)例. 采用configuration 選項(xiàng)作為初始化參數(shù)。可用的選項(xiàng)有:
示例 :針對wkhtmltopdf不在系統(tǒng)路徑中(不在$PATH里面)
PATH里面):
config = pdfkit.configuration(wkhtmltopdf='/opt/bin/wkhtmltopdf'))
pdfkit.from_string(html_string, output_file, configuration=config)
問題
IOError:'No wkhtmltopdf executable found':
確保 wkhtmltopdf 在你的系統(tǒng)路徑中(PATH), 會通過 configuration進(jìn)行了配置 (詳情看上文描述)。 在Windows系統(tǒng)中使用where wkhtmltopdf命令 或 在 linux系統(tǒng)中使用 which wkhtmltopdf 會返回 wkhtmltopdf二進(jìn)制可執(zhí)行文件所在的確切位置.
如果出現(xiàn)這個(gè)錯(cuò)誤意味著 PDFKit不能處理一個(gè)輸入。你可以嘗試直接在錯(cuò)誤信息后面直接運(yùn)行一個(gè)命令來查看是什么導(dǎo)致了這個(gè)錯(cuò)誤 (某些版本的 wkhtmltopdf會因?yàn)槎五e(cuò)誤導(dǎo)致處理失敗)
確保兩項(xiàng):
1)、你的系統(tǒng)中有中文字體
2)、在html中加入
下面是我隨便寫的一個(gè)HTML表格:
<html>
<head><meta charset="UTF-8"></head>
<body>
<table width="400" border="1">
<tr>
<th align="left">Item....</th>
<th align="right">1</th>
</tr>
<tr>
<td align="left">衣服</td>
<td align="right">1.10</td>
</tr>
<tr>
<td align="left">化妝品</td>
<td align="right">.00</td>
</tr>
<tr>
<td align="left">食物</td>
<td align="right">0.40</td>
</tr>
<tr>
<th align="left">tOTAL</th>
<th align="right">01.50</th>
</tr>
</table>
</body>
</html>
下面是生成的PDF截圖
正則表達(dá)式 描述 匹配結(jié)果
\d+(\.\d*)? 任意整數(shù)和浮點(diǎn)數(shù) 0.004 2 75.
\b[^\Wa-z0-9_][^\WA-Z0-9_]*\b 首字母只能大寫 Boo Foo
^http:\/\/([\w-]+(\.[\w-]+)+(\/[\w-.\/\?%&=\u4e00-\u9fa5]*)?)?$ 驗(yàn)證網(wǎng)址 http://www.baidu.com/?id=1
^[\u4e00-\u9fa5]{
0,}$ 驗(yàn)證漢字 漢字漢字
\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 驗(yàn)證電子郵件 example@163.com
^[1-9]([0-9]{
16}|[0-9]{
13})[xX0-9]$ 驗(yàn)證身份證 14525419951215445X
^13[0-9]{
1}[0-9]{
8}|^15[9]{
1}[0-9]{
8} 驗(yàn)證手機(jī)號 138459572***
^(25[0-5]|2[0-4][0-9]|[0-1]{
1}[0-9]{
2}|[1-9]{
1}[0-9]{
1}|[1-9]) 驗(yàn)證IP 192.168.1.1
\.(25[0-5]|2[0-4][0-9]|[0-1]{
1}[0-9]{
2}|[1-9]{
1}[0-9]{
1}|[1-9]|0)
\.(25[0-5]|2[0-4][0-9]|[0-1]{
1}[0-9]{
2}|[1-9]{
1}[0-9]{
1}|[1-9]|0)
\.(25[0-5]|2[0-4][0-9]|[0-1]{
1}[0-9]{
2}|[1-9]{
1}[0-9]{
1}|[0-9])$
^[a-zA-Z0-9]+([a-zA-Z0-9\-\.]+)?\.s|)$ 驗(yàn)證域名 baidu.com
^([a-zA-Z]\:|\\)\\([^\\]+\\)*[^\/:*?"<>|]+\.txt(l)?$ 驗(yàn)證文件路徑 C:\user\wo
<(.*)>(.*)<\/(.*)>|<(.*)\/> HTML標(biāo)簽匹配(需修改) xxxx
re.I 使匹配對大小寫不敏感
re.L 做本地化識別匹配
re.M 多行匹配,影響^和$
re.S 使.匹配包括換行在內(nèi)的所有字符
re.U 根據(jù)Unicode字符集解析字符.這個(gè)標(biāo)志影響\w \W \b \B
re.X 該標(biāo)志通過給予你更靈活的格式以便你將正則表達(dá)式寫的更易于理解.
# 例子 result = re.match('^The.*?(\d+).*?phone.', content, re.S)
^ 匹配字符串開頭
$ 匹配字符串結(jié)尾
. 匹配人以字符,除了換行符號.當(dāng)re.DOTAALL標(biāo)記被指定時(shí),則可以匹配包括換行符的任意字符.
[...] 用來表示一組字符,單獨(dú)列出:[amk]匹配a,m或k
[^...] 不在[]中的字符:[^amk]匹配除amk之外的字符
re* 匹配0個(gè)或多個(gè)的表達(dá)式
re+ 匹配1個(gè)或多個(gè)的表達(dá)式
re? 匹配0個(gè)或1個(gè)由前面的正則表達(dá)式定義的片段,非貪婪方式.
re{
n} 精準(zhǔn)匹配n個(gè)前面表達(dá)式
re{
n,} 匹配大于等于n個(gè)前面表達(dá)式
re{
n,m} 匹配n到m個(gè)前面的表達(dá)式定義的片段,貪婪方式
a|b 匹配a或b
(re) 對正則表達(dá)式分組,并記住匹配的文本
(?imx) 正則表達(dá)式包含三種可選標(biāo)志,imx,只影響括號中的區(qū)域.
(?-imx) 正則表達(dá)式關(guān)閉imx可選標(biāo)志,只影響括號中的區(qū)域.
(?:re) 類似(...)但不表示一個(gè)組
(?imx:re) 在括號中使用imx可選標(biāo)志
(?-imx:re) 在括號中不是用imx可選標(biāo)志
(?#...) 注釋
(?=re) 前向肯定界定符.如果所含正則表達(dá)式,以...表示,在當(dāng)前位置成功匹配時(shí)成功,否則失敗.但一旦所含表達(dá)式已經(jīng)嘗試,匹配引擎根本沒有提高,模式的剩余部分還要嘗試界定符右邊.
(?!re) 前向否定界定符.與肯定界定符相反;當(dāng)所含的表達(dá)式不能在字符串當(dāng)前位置匹配成功時(shí)成功.
(?>re) 匹配的獨(dú)立模式,省去回朔.
\w 匹配字符數(shù)字以及下劃線
\W 匹配非字母數(shù)字下劃線
\s 匹配任意空白字符,等價(jià)于[\t\n\r\f]
\S 匹配任意非空白字符
\d 匹配任意數(shù)字
\D 匹配任意非數(shù)字
\A 匹配字符串開始
\Z 匹配字符串結(jié)束,如果是存在換行,只匹配到換行前的結(jié)束字符串.
\z 匹配字符串結(jié)束
\G 匹配最后匹配完成的位置
\b 匹配一個(gè)單詞邊界,也就是指單詞和空格之間的位置
\B 匹配非單詞邊界
\n \t 匹配一個(gè)換行符,一個(gè)制表符
\1...\9 匹配第n個(gè)分組的內(nèi)容
正則表達(dá)式使用 反斜杠 來表示特殊形式,或者把特殊字符 轉(zhuǎn)義成普通字符 。
而 反斜杠 在普通的 Python 字符串 里也有 相同的作用 ,所以就產(chǎn)生了 沖突 。
解決辦法是對于正則表達(dá)式樣式使用 Python 的原始字符串表示法;在帶有 ‘r’ 前綴的字符串字面值中, 反斜杠不必做任何特殊處理 。
import re
if re.search(r'\\d', 'I have one nee\dle') is not None:
print('match it',re.search(r'\\d', 'I have one nee\dle').group(0))
else:
print('not match')
# match it \d
import re
content = 'The 123456 is my one phone number.'
print('貪婪匹配:')
result = re.match(r'^The.*(\d+).*', content) #使用match匹配, 第一個(gè)參數(shù)為正則表達(dá)式, 第二個(gè)為要匹配的字符串
print(result.group()) #輸出匹配內(nèi)容
print('result = %s'%result.group(1)) #輸出第一個(gè)被()包裹的內(nèi)容
print('-'*20)
print('非貪婪匹配:')
result = re.match(r'^The.*?(\d+).*', content)
print(result.group())
print('result = %s'%result.group(1))
# 貪婪匹配:
# The 123456 is my one phone number.
# result = 6
# --------------------
# 非貪婪匹配:
# The 123456 is my one phone number.
# result = 123456
import re
content = '(百度)www.baidu.com'
result = re.match('(百度)www.baidu.com', content)
result2 = re.match('\(百度\)www\.baidu\.com', content)
if result:
print(result.group())
else:
print('result = None')
if result2:
print(result2.group())
else:
print('result2 = None')
# result = None
# (百度)www.baidu.com
import re
content1 = '2016-1-1 12:01'
content2 = '2017-1-1 12:02'
content3 = '2018-1-1 12:03'
pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)
print(result1, result2, result3)
#2016-1-1 2017-1-1 2018-1-1
import re
regex = '(foo\w)(\w)'
m = re.match(r'(foo\w)(\w)','fooasdfooasd')
if m is not None:
print(m.group(1))
print(m.groups())
#輸出
#fooa
#('fooa', 's')
import re
regex = '<(.*)>(.*)<\/(.*)>|<(.*)\/>'
m = re.search(regex,"aa<a>aaaa</a>")
#一樣只有search能匹配到標(biāo)簽
if m is not None:
print(m)
print(m.group())
# 結(jié)果
# <re.Match object; span=(2, 13), match='<a>aaaa</a>'>
# <a>aaaa</a>
import re
text = "I am so happy! "
array1 = re.findall("[a-zA-Z]", text)
array2 = re.findall("[a-zA-Z]+", text)
print(array1)
print(array2)
#結(jié)果
# ['I', 'a', 'm', 's', 'o', 'h', 'a', 'p', 'p', 'y']
# ['I', 'am', 'so', 'happy']
import re
regex = 'apple'
m = [ g.group() for g in re.finditer(regex,'apple1 apple2 apple3')]
print(m)
#輸出
#['apple', 'apple', 'apple']
import re
list = [
'aaa,bbb,ccc',
'ddd,eee,fff',
]
for i in list:
print(re.split(',',i))
# ['aaa', 'bbb', 'ccc']
# ['ddd', 'eee', 'fff']
import re
st = "hello 2019"
st = re.sub("([0-9]+)","yudengwu",st)
print(st)
#結(jié)果
# hello yudengwu
*請認(rèn)真填寫需求信息,我們會在24小時(shí)內(nèi)與您取得聯(lián)系。