一、Requests庫的使用
Requests 唯一的一個非轉基因的 Python HTTP 庫,人類可以安全享用。
(1)安裝、在cmd下執行:pip install requests(2)TP協議對資源的操作
GET 獲取URL位置的資源HEAD 獲取URL位置資源的頭部信息
POST 向URL位置的資源後附加新的數據
PUT 覆蓋URL位置的資源
PATCH 局部更新URL位置的資源
DELETE 刪除URL位置的資源
(3)requests庫中的方法
requests.request() 構造請求,支持下面各方法的基礎requests.get() 獲取HTML網頁的主要方法,對應於HTTP的GET
requests.head() 獲取HTML網頁的頭信息的方法
requests.post() 向HTML網頁提交POST請求的方法,對應HTTP的POST
requests.put() 向HTML提交PUT請求,對應HTTP的PUT
requests.patch() 對應於HTTP的PATCH
requests.delete() 向HTTP頁面提交刪除請求,對應HTTP的DELETE
(4)方法的原型及用法
5.1、get方法原型requests.get(url,params=None,**kwargs)
5.2、params url中的額外參數,字典或字節流格式,可選
**kwargs 12個控制訪問的參數,如headers等
5.3、post方法原型
requests.post(url,data=None,json=None,**kwargs)
payload={"key":"value"}
r=requests.post(url,data=payload)
5.4、put,patch與post類似
5.5、delete方法原型
request.deete(url,**kwargs)
requests.request(method,url,**kwargs)
method 請求方式,get,put,post...
(5)**kwargs(訪問控制參數)
5.1、params 字典或字節序列,作爲參數增加到url中
如:
kv={'k1':'v1','k2':'v2'}
r=requests.request('GET','http://python123.io/ws',params=kv)
print(r.url)
結果:http://python123.io/ws?k1=v1&k2=v2
5.2、data 字典,字節序或文件對象,作爲Request的內容,post請求的參數
5.3、json JSON格式數據,作爲Request的內容
5.4、headers 字典,HTTP定製頭
如:
h={'User-Agent':'...'}
r=requests.get(url,headers=h)
5.5、cookies 字典或CookieJar,Request中的cookie
5.6、auth 元組,支持HTTP認證功能
5.7、files 字典,傳輸文件
如:
fs={'file':open('data.xls','rb')}
r=requests.request('POST',url,files=fs)
5.8、timeout 設定超時時間,以秒爲單位,超時會產生timeout異常
r=requests.request('GET',url,timeout=10)
5.9、proxies 字典,設置訪問代理服務器,可以防止逆追蹤
如:
pxs={'http':'http://user:[email protected]:1234','https':'https://10.10.10.1:4321'}
r=requests.get(url,proxies=pxs)
5.10、allow_redirects True/False 默認True,重定向開關
5.11stream True/False 默認True,立即下載開關
5.12、verify True/False 默認True,認證SSL證書開關
5.13、cert 本地SSL證書路徑
(5)Response對象的屬性
r=requests.get() //r爲Response對象r.status_code HTTP請求的返回狀態碼
r.text HTTP響應內容的字符串形式,即url對應的頁面內容
r.encoding 從HTTP header中猜測的響應內容的編碼方式
r.apparent_encoding 從內容中分析出的響應內容的編碼方式
r.content HTTP響應內容的二進制形式
(6)Requests庫的異常
requests.ConnectionError 網絡連接異常,如DNS查詢失敗、拒絕連接
requests.HTTPError HTTP錯誤異常
requests.URLRequired URL缺失異常
requests.TooManyRedirects 超過最大重定向次數產生的重定向異常
requests.ConnectTimeout 連接遠程服務器超時異常
requests.Timeout 請求URL超時產生的超時異常
raise_for_status 如果返回的status_code不是200產生requests.HTTPError
實例一:get方法的使用
import requests
url='https://blog.csdn.net/qq_32261191/article/details/80338091'
#使用try...except捕捉異常
try:
#請求url
r=requests.get(url)
#請求狀態碼不是200,則產生異常
r.raise_for_status()
#設置顯示的編碼爲apparent_encoding檢測到的編碼格式
r.encoding=r.apparent_encoding
#輸出前1000個字符
print(r.text[:1000])
except:
print("ERROR!!!")
實例二:修改headers
import requests
url='https://blog.csdn.net/qq_32261191/article/details/80338091'
#使用try...except捕捉異常
h={'user-agent':'Mozilla/5.0'}
try:
#請求url
r=requests.get(url)
#默認請求頭
print(r.request.headers)
r=requests.get(url,headers=h)
#請求狀態碼不是200,則產生異常
r.raise_for_status()
#設置顯示的編碼爲apparent_encoding檢測到的編碼格式
r.encoding=r.apparent_encoding
#修改後的請求頭
print(r.request.headers)
except:
print("ERROR!!!")
實例三:GET傳入參數
百度搜索ip時URL爲:http://www.baidu.com/s?wd=ipimport requests
url='http://www.baidu.com/s'
#GET傳的參數設置
kv={'wd':'ip'}
#使用try...except捕捉異常
try:
#請求url:http://www.baidu.com/s?wd=ip
r=requests.get(url,params=kv)
#請求狀態碼不是200,則產生異常
r.raise_for_status()
#設置顯示的編碼爲apparent_encoding檢測到的編碼格式
r.encoding=r.apparent_encoding
#輸出請求的url,
print(r.request.url)
except:
print("ERROR!!!")
實例四:圖片下載
import requests,os
#圖片的URL
url="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1526560867378&di=da4e7dc76d9b54647d1356ba6d3d73ef&imgtype=0&src=http%3A%2F%2Fi2.3conline.com%2Fimages%2Fpiclib%2F201006%2F23%2Fbatch%2F1%2F62615%2F12772647784528c3naeziee.jpg"
#設置存放圖片的目錄
path="F://Apicts//"
try:
#如果目錄不存在,創建目錄
if not os.path.exists(path):
os.mkdir(path)
#請求url
r=requests.get(url)
#截取URL中最後一個"="之後的內容,視情況而定
path=path+url.split('=')[-1]
#創建文件並寫入
with open(path,'wb') as f:
f.write(r.content)
f.close()
print("圖片已下載!")
except:
print("ERROR!!!")
二、Beautiful Soup庫的使用
Beautiful Soup 是一個可以從HTML或XML文件中提取數據的Python庫
(1)安裝beautiful soup庫,pip install beautifulsoup4(2)簡單的網站克隆實例
import requests
#BeautifulSoup庫簡寫爲bs4,從bs4庫中導入BeautifulSoup類
from bs4 import BeautifulSoup
r=requests.get("http://www.baidu.com")
r.encoding=r.apparent_encoding
demo=r.text
#使用html.parser解析器解析得到的html頁面
soup=BeautifulSoup(demo,"html.parser")
#輸出解析的結果
print(soup.prettify())
demo=soup.prettify()
#創建一個abc.html文件,設置文件編碼爲目標網頁的編碼
fn=open("abc.html",'w',encoding=r.encoding)
#寫入demo
fn.write(demo)
fn.close()
(3)BeautifulSoup庫可以使用的解析器解析器 使用方法 條件
bs4的HTML解析器 BeautifulSoup(mk,'html.parser') 安裝bs4
lxml的HTML解析器 BeautifulSoup(mk,'lxml') 安裝lxml庫
lxml的XML解析器 BeautifulSoup(mk,'xml') 安裝lxml庫
html5lib的解析器 BeautifulSoup(mk,'html5lib') 安裝html5lib
(4)基本元素
Tag 標籤,最基本的信息組織單元,用<>和</>標明開頭和結尾
Name 標籤的名字,<p>...</p>的名字是p,格式:<tag>.name
Attributes 標籤的屬性,字典形式,格式:<tag>.attrs
NavigableString 標籤非屬性字符串,<>...</>中的...,格式:<tag>.string
Comment 標籤內字符串的註釋部分,一種特殊的Comment類型
接上面的代碼,如:
soup.title 表示獲取解析後的頁面的<title>標籤
soup.title.name 表示獲取title標籤的名字
soup.title.parent.name 表示獲取title標籤的上一層標籤的名字
soup.title.parent.parent.name 表示獲取title標籤的上上層標籤的名字
類型全爲string
(5)標籤的屬性
soup.a.attrs 獲取標籤a的屬性,字典類型soup.a.attrs['href'] 獲取a標籤屬性中href的值
soup.a.string 獲取a標籤中的字符串,即<a>...</a>中的...
通過string屬性可以查看註釋和字符串,通過類型區分註釋
(6)HTML文檔遍歷
6.1、標籤樹的下行遍歷
.contents 獲取子標籤列表,將標籤所有子標籤存入列表.children 循環遍歷子標籤
.descendants 包含所有子孫標籤
soup.body.contents 獲取body標籤的所有子標籤
#遍歷body的子標籤
for child in soup.body.children:
print(child)
6.2、標籤樹的上行遍歷
.parent 標籤的父標籤.parents 標籤的先輩標籤
#標籤樹上行遍歷
for parent in soup.a.parents:
print(parent.name)
6.3、標籤樹的平行遍歷
.next_sibling 返回HTML文本順序的下一個平行節點標籤
.previous_sibling 返回HTML文本順序的上一個平行節點標籤
.next_siblings 返回HTML文本順序的後續所有平行節點標籤
.previous_siblings 返回HTML文本順序的前續所有平行節點標籤
獲取的結果不一定是標籤類型
#遍歷後續節點
for sibling in soup.a.next_siblings:
print(sibling)
#遍歷前續節點
for sibling in soup.a.previous_siblings:
print(sibling)
(7)find_all()函數使用
find_all(name,attrs,recursive,string,**kwargs)返回爲列表類型
name 要查找的標籤
attrs 要查找的標籤屬性值
recursive 是否全部查找,默認True
string 查找標籤字符串域的字符串
<tag>(...) <==> <tag>.find_all(...) 等價
soup(...) <==> soup.find_all(...)
soup.find_all('p','course') 查找<p>標籤中包含course的字符串
soup.find_all(string="abc") 查找<>...<>中...包含abc的字符串
#遍歷頁面中所有鏈接
ls=soup.find_all('a')
for j in ls:
print(j)
擴展方法(參數與find_all相同)
.find() 搜索且只返回一個結果,str類型
.find_parents() 先輩節點中搜索,返回列表類型
.find_parent() 先輩節點返回一個結果,str類型
.find_next_siblings() 後續平行節點搜索,返回列表類型
.find_next_sibling() 後續平行節點搜索,返回str類型
.find_previous_sibligs() 前序搜索,返回列表類型
.find_previous_siblig() 前序搜索一個,str類型
三、Re庫的使用
(1)正則表達式常用操作符
. 表示單個字符
[] 字符集 如[abc]表示a、b、c,[a-z]表示a-z
[^] 非字符集 如[^abc]表示除a、b、c外的字符集
* 前一個字符0或無限次 如abc*表示ab,abc,abccc...
+ 前一個字符1或無限次 如abc+表示abc,abcc,abccc,...
? 前一字符0或1次 如abc?表示ab、abc
| 表示左右任意一個 如ab|cd表示ab、cd
{m} 擴展前一字符m次 如ab{2}c表示abbc
{m,n} 擴展前一字符m-n次 如ab{1,2}表示abc、abbc
^ 匹配字符串開頭 如^abc表示匹配字符串開頭爲abc的字符串
$ 匹配字符串結尾 如abc$表示結尾爲abc的字符串
() 分組標記,內部只能用| 如(abc)表示abc,(a|b)表示a、b
\d 數字,等價[0-9]
\w 單詞字符,等價[A-Za-z0-9_]
(2)Re庫主要功能函數
re.search() 搜索字符串中匹配的第一個對象,match對象
re.match() 從字符串的開始位置起匹配正則表達式,match對象
re.findall() 搜索字符串,返回符合的全部字符串,列表
re.split() 分割匹配的結果的列表爲,子列表
re.finditer() 搜索字符串,返回結果的迭代類型,每個迭代爲match類型
re.sub() 在一個字符串中替換所有匹配正則表達式的子串,返回替換後的結果
2.1、re.search函數
re.search(pattern,string,flags=0)
pattern 正則表達式的字符串或原生字符串
string 待匹配的字符串
flags 正則表達式使用時的控制標記
flags的值有
re.I 忽略正則表達式的大小寫,使[a-z]可以匹配大寫
re.M 正則表達式中的^操作符能將給定字符串的每行當中匹配開始
re.S 正則表達式中的.操作符能匹配所有字符,默認匹配除換行外的字符
import re
match=re.search(r'[1-9]\d{5}','BIT 100081')
if match:
print(match.group(0))
運行上面代碼輸出:100081,使用match函數輸出爲空,使用findall函數成功輸出,search,match,findall,finditer函數參數相同
2.2、re.split函數
re.split(pattern,string,maxsplit=0,flags=0)
其他3個參數同上,maxsplot表示最大分割數,剩餘部分作爲最後一個元素輸出
import re
ls=re.split(r'[1-9]\d{5}','BIT 100081 ABC 100081')
print(ls)
ls=re.split(r'[1-9]\d{5}','BIT 100081 ABC 100081',maxsplit=1)
print(ls)
2.3、re.finditer函數import re
for m in re.finditer(r'[1-9]\d{6}','BIT100081 TSU 100084'):
if m:
print(m.group(0))
2.4、re.sub函數re.sub(pattern,repl,string,count=0,flags=0)
repl表示替換匹配字符串的字符串
count表示匹配的次數
import re
ls=re.sub(r'[1-9]\d{5}','8888','BIT 100081 ABC 100081')
print(ls)
(3)match對象的屬性和方法
屬性.string 待匹配的文本
.re 匹配時使用的pattern對象(正則表達式)
.pos 正則表達式搜索文本的開始位置
.endpos 正則表達式搜索文本的結束位置
方法
.group(0) 獲得匹配後的字符串
.start() 匹配字符串在原始字符串的開始位置
.end() 匹配字符串在原始字符串的結束位置
.span() 返回(.start(),.end())元組
import re
m=re.search(r'[1-9]\d{5}','BIT 100081 ABC 100081')
print(m.string)
print(m.re)
print(m.pos)
print(m.endpos)
print(m.group(0))
print(m.start())
print(m.end())
print(m.span())
(4)貪婪匹配(默認)和最小匹配match=re.search(r'PY.*N','PYANBNCNDN')
match.group(0)
這段代碼會返回PYANBNCNDN
如果想要得到最小匹配,在*和N直接加入?即可,在*,+,?,{m,n}後加?就擴展爲對應的最小匹配