日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python爬虫基本库的使用

發(fā)布時間:2024/2/28 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python爬虫基本库的使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

已寫章節(jié)

第一章 網(wǎng)絡(luò)爬蟲入門
第二章 基本庫的使用
第三章 解析庫的使用
第四章 數(shù)據(jù)存儲
第五章 動態(tài)網(wǎng)頁的抓取

文章目錄

      • 已寫章節(jié)
  • 第二章 基本庫的使用
    • 2.1 urllib庫的使用(非重點)
      • 2.1.1 request模塊
      • 2.1.2 error模塊
      • 2.1.3 parse模塊
    • 2.2 requests庫的使用(重點)
      • 2.2.1. requests庫的介紹
      • 2.2.2 requests庫的安裝
      • 2.2.3 requests庫的使用
        • 2.2.3.1 requests.get()方法
        • 2.2.3.2 requests.request()方法
        • 2.2.3.3 處理requests庫的異常
        • 2.2.3.4 發(fā)送POST請求
        • 2.2.3.5 requests庫的使用實例:TOP250電影數(shù)據(jù)、抓取二進制數(shù)據(jù)
    • 2.3 正則表達式(重點)
      • 2.3.1 正則表達式的介紹
      • 2.3.2 Re庫
        • 2.3.2.1 Re庫的介紹
        • 2.3.2.2 Re庫的使用
          • 2.3.2.2.1 re.match()方法
          • 2.3.2.2.2 使用分組
          • 2.3.2.2.3 通用匹配和匹配操作符
          • 2.3.2.2.4 貪婪與非貪婪
          • 2.3.2.2.5 控制標記
          • 2.3.2.2.6 re.search()
          • 2.3.2.2.7 re.findall()
          • 2.3.2.2.8 re.sub()
          • 2.3.2.2.9 re.compile()
      • 2.3.3 使用Re來爬取tx視頻


第二章 基本庫的使用



2.1 urllib庫的使用(非重點)


urllib的官方文檔

urllib是Python中自帶的HTTP請求庫,也就是說不用額外安裝就可以使用,它包含如下四個模塊:

  • requests:基本的HTTP請求模塊,可以模擬發(fā)送請求
  • error:異常處理模塊
  • parse:一個工具模塊,提供了許多URL處理方法,比如拆分、解析、合并等。
  • robotparser:它主要用來識別網(wǎng)站的robots.txt文件,讓后判斷哪些內(nèi)容可以爬取,哪些不能爬取,用得比較少。

2.1.1 request模塊



  • 發(fā)送請求
# 2.1 使用urllib庫中的request模塊發(fā)送一個請求的例子 import urllib.requestresponse = urllib.request.urlopen('http://www.baidu.com') print(response.read().decode('utf-8'))

使用request.urlopen()來向百度首頁發(fā)起請求,返回的是http.client.HTTPResponse對象,這個對象主要包含read()、readinto()、getheader(name)、getheaders()、fileno()等方法,以及msg、version、status、reason、debuglevel、closed等屬性。將返回的HTML代碼以utf-8的編碼方式讀取并打印出來。上面的代碼執(zhí)行后將返回百度的主頁的HTML代碼。

我運行的效果如下:

<!DOCTYPE html><!--STATUS OK--><html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta content="always" name="referrer"><meta name="theme-color" content="#2932e1"><meta name="description" content="全球最大的中文搜索引擎、致力于讓網(wǎng)民更便捷地獲取 信息,找到所求。百度超過千億的中文網(wǎng)頁數(shù)據(jù)庫,可以瞬間找到相關(guān)的搜索結(jié)果。"> 后面省略無數(shù)字......

接下來再看這個例子:

# 2.2 使用urllib中的request模塊發(fā)起一個請求并獲取response對象中的信息的例子 import urllib.requestresponse = urllib.request.urlopen("http://www.python.org") print(response.read().decode('utf-8')[:100]) # 截取返回的html代碼的前100個字符的信息 print("response的類型為:" + str(type(response))) print("response的狀態(tài)為:" + str(response.status)) print("response的響應(yīng)的頭信息:" + str(response.getheaders())) print("response的響應(yīng)頭中的Server值為:" + str(response.getheader('Server')))

上面的代碼使用urlopen()方法向指定的鏈接發(fā)起了一個請求,得到一個HTTPResponse對象,然后調(diào)用HTTPResponse的方法和屬性來獲取請求的狀態(tài)、請求頭信息等

下面是我的執(zhí)行結(jié)果:

<!doctype html> <!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]--> <!- response的類型為:<class 'http.client.HTTPResponse'> response的狀態(tài)為:200 response的響應(yīng)的頭信息:[('Connection', 'close'), ('Content-Length', '50890'), ('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'DENY'), ('Via', '1.1 vegur, 1.1 varnish, 1.1 varnish'), ('Accept-Ranges', 'bytes'), ('Date', 'Mon, 17 May 2021 08:59:57 GMT'), ('Age', '1660'), ('X-Served-By', 'cache-bwi5163-BWI, cache-hkg17920-HKG'), ('X-Cache', 'HIT, HIT'), ('X-Cache-Hits', '1, 3886'), ('X-Timer', 'S1621241997.260514,VS0,VE0'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')] response的響應(yīng)頭中的Server值為:nginx

  • data參數(shù)

data參數(shù)是可選的,該參數(shù)是bytes類型,需要使用bytes()方法將字典轉(zhuǎn)化為字節(jié)類型,并且,該參數(shù)只能在POST請求中使用。

# 2.3 data參數(shù)的使用 import urllib.request# 使用urllib中的parse模塊中的urlencode方法來將字典轉(zhuǎn)化為字節(jié)類型,編碼方式為utf-8 data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8') response = urllib.request.urlopen('http://httpbin.org/post', data=data) print(response.read())

這次我們請求的是http://httpbin.org/post這個網(wǎng)址,這個網(wǎng)址可以提供http請求測試,它可以返回請求的一些信息,其中包括我們傳遞的data參數(shù)。



  • timeout參數(shù)

timeout參數(shù)用來設(shè)置超時時間,單位為秒,意思是如果請求超出了設(shè)置的這個時間,還沒有得到響應(yīng),就會拋出異常。

# 2.4 timeout參數(shù)的使用 import urllib.requestresponse = urllib.request.urlopen('http://www.baidu.com', timeout=1) print(response.read())

運行結(jié)果就不展示了。



  • 其他參數(shù)

除了data參數(shù)和timeout參數(shù)外,還有context參數(shù),它必須是ssl.SSLContext類型,用來指定SSL設(shè)置



Request類

urlopen()可以實現(xiàn)基本的請求的發(fā)起,但這不能構(gòu)造一個完整的請求,如果要在請求中加入Headers等信息,就可以利用更強大的Request類來構(gòu)建。

# 2.5 Request類的使用 import urllib.requestrequest = urllib.request.Request('https://python.org') print(type(request)) response = urllib.request.urlopen(request) # 傳入的是Request對象 print(response.read().decode('utf-8'))

request的構(gòu)造方法:

Requests(url, data, headers, origin_host, unverifiablem, method)

  • url:請求的url鏈接
  • data:必須為字節(jié)流(bytes)類型
  • headers:請求頭信息
  • origin_req_host:請求方的host名稱或者IP地址
  • unverifiable:表示這個請求是否是無法驗證的,默認為False。
  • method:指示請求使用的方法,比如:GET、POST、PUT等

下面是例子:

# 2.6 Request類的使用 from urllib import request, parseurl = "http://httpbin.org/get" headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)','Host': 'httpbin.org' } dict = {'name': 'Germey' } data = bytes(parse.urlencode(dict), encoding='utf8') req = request.Request(url=url, data=data, headers=headers, method='GET') response = request.urlopen(req) print(response.read().decode('utf-8'))

我們依然請求的是測試網(wǎng)址http://httpbin.org/get,它會返回我們發(fā)起的請求信息,下面是我的運行結(jié)果:

{"args": {}, "headers": {"Accept-Encoding": "identity", "Content-Length": "11", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)", "X-Amzn-Trace-Id": "Root=1-60a236ed-01f68c862b09c8934983ae80"}, "origin": "221.176.140.213", "url": "http://httpbin.org/get" }

從結(jié)果中,我們可以看到我們發(fā)起的請求中包含了我們自己設(shè)置的User-Agent,Host和我們請求中包含的數(shù)據(jù) ‘name’: ‘Germey’。



2.1.2 error模塊

urllib中的error模塊定義了由request模塊產(chǎn)生的異常,如果出現(xiàn)了問題,request模塊就會拋出error模塊中的異常。

下面介紹其中用得比較多的兩個異常:URLError和HTTPError。



  • URLError

    URLError類是error異常模塊的基類,由request模塊產(chǎn)生的異常都可以通過捕獲這個異常來處理。

    # 2.7 URLError的使用例子 from urllib import request, error# 打開一個不存在的網(wǎng)頁 try:response = request.urlopen('https://casdfasf.com/index.htm') except error.URLError as e:print(e.reason)

    運行結(jié)果:

    [Errno 11001] getaddrinfo failed


  • HTTPError

    它是URLError的子類,專門用來處理HTTP請求錯誤,比如認證請求失敗等。它有如下3個屬性:

  • code:返回HTTP狀態(tài)碼
  • reason:返回錯誤的原因
  • headers:返回請求頭
  • # 2.8 HTTPError對象的屬性 from urllib import request, errortry:response = request.urlopen('https://cuiqingcai.com/index.htm') except error.HTTPError as e:print(e.reason, e.code, e.headers, sep='\n')

    運行結(jié)果:

    Not Found 404 Server: GitHub.com Date: Tue, 16 Feb 2021 03:01:45 GMT Content-Type: text/html; charset=utf-8 X-NWS-UUID-VERIFY: 8e28a376520626e0b40a8367b1c3ef01 Access-Control-Allow-Origin: * ETag: "6026a4f6-c62c" x-proxy-cache: MISS X-GitHub-Request-Id: 0D4A:288A:10EE94:125FAD:602B33C2 Accept-Ranges: bytes Age: 471 Via: 1.1 varnish X-Served-By: cache-tyo11941-TYO X-Cache: HIT X-Cache-Hits: 0 X-Timer: S1613444506.169026,VS0,VE0 Vary: Accept-Encoding X-Fastly-Request-ID: 9799b7e3df8bdc203561b19afc32bb5803c1f03c X-Daa-Tunnel: hop_count=2 X-Cache-Lookup: Hit From Upstream X-Cache-Lookup: Hit From Inner Cluster Content-Length: 50732 X-NWS-LOG-UUID: 5426589989384885430 Connection: close X-Cache-Lookup: Cache Miss


2.1.3 parse模塊

parse模塊是用來處理url的模塊,它可以實現(xiàn)對url各部分的抽取、合并以及連接裝換等。

下面介紹parse模塊中常用的幾個方法:


  • urlparse()

    實現(xiàn)url的識別和分段

    # 2.9 urllib庫中parse模塊中urlparse()方法的使用 from urllib.parse import urlparseresult = urlparse('http://www.biadu.com/index.html;user?id=5#comment') print(type(result), result)result1 = urlparse('www.biadu.com/index.html;user?id=5#comment', scheme='https') print(type(result1), result1)result2 = urlparse('http://www.baidu.com/index.html#comment', allow_fragments=False) print(type(result2), result2)result3 = urlparse('http://www.baidu.com/index.html#comment', allow_fragments=False) print(result3.scheme, result3[0], result3.netloc, result3[1], sep="\n")

    運行結(jié)果:

    <class 'urllib.parse.ParseResult'> ParseResult(scheme='http', netloc='www.biadu.com', path='/index.html', params='user', query='id=5', fragment='comment') <class 'urllib.parse.ParseResult'> ParseResult(scheme='https', netloc='', path='www.biadu.com/index.html', params='user', query='id=5', fragment='comment') <class 'urllib.parse.ParseResult'> ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html#comment', params='', query='', fragment='') http http www.baidu.com www.baidu.com

    可以看到,urlparse()方法將url解析為6部分,返回的是一個ParseResult對象,這6部分是:

  • scheme:😕/前面的部分,指協(xié)議
  • netloc:第一個/的前面部分,指域名
  • path:第一個/后面的部分,指訪問路徑
  • params:;后面的部分,指參數(shù)
  • query:問號后面的內(nèi)容,指查詢條件
  • fragment:#號后面的內(nèi)容,值錨點
  • 所以,可以得出一個標準的鏈接格式:

    scheme://netloc/path;params?query#fragment

    一個標準的URL都會符合這個規(guī)則,我們就可以使用urlparse()這個方法來將它拆分開來。

    urlparse()方法還包含三個參數(shù):

    urlstring:必選項,即待解析的URL

    scheme:默認協(xié)議,假如這個鏈接沒有帶協(xié)議信息,會將這個作為默認的協(xié)議。

    allow_fragments:即是否忽略fragment。如果它被設(shè)置為false,fragment就會被忽略,它會被解析為path、params或者query的一部分,而fragment部分為空



  • urlunparse()

    它和urlparse()方法相反,它接收的參數(shù)是一個可迭代對象(常見的有列表、數(shù)組、集合),它的長度必須為6。

    # 2.10 parse模塊中的urlparse方法的使用 from urllib.parse import urlunparsedata = ['http', 'www.baidu.com', 'index.html', 'user', 'a=6', 'comment'] print(urlunparse(data))

    上面的例子中傳入的是一個包含6個元素的列表,當(dāng)然可以是其他類型,如元組,只需要這個可迭代對象的長度為6個就可以了。



  • urlsplit()

    和urlparse()方法相似,只不過它不再單獨解析params這一部分,而將params加入到path中,只返回5個結(jié)果

    # 2.11 parse模塊中的urlsplit方法的使用 from urllib.parse import urlsplitresult = urlsplit('http://www.baidu.com/index.html;user?id=5#comment') print(result)

    運行結(jié)果:

    SplitResult(scheme='http', netloc='www.baidu.com', path='/index.html;user', query='id=5', fragment='comment')


  • urlunsplit()

    和urlsplit()方法相反,傳入的參數(shù)也是一個可迭代的對象,例如列表、元組等,長度必須為5。

    # 2.12 parse模塊中的urlunsplit方法的使用 from urllib.parse import urlunsplitdata = ['http', 'www.baidu.com', 'index.html', 'a=6', 'comment'] print(urlunsplit(data))

    運行結(jié)果:

    http://www.baidu.com/index.html?a=6#comment


  • urljoin()

    該方法接收兩個參數(shù),一個是base_url,另外一個是新的url,該方法會分析新url中的scheme、netloc、path三部分的內(nèi)容是否存在,如果某個不存在,就用base_url中的來替換。



  • urlencode()

    將字典類型轉(zhuǎn)換為url中的參數(shù)

    # 2.13 parse模塊中的urlencode方法的使用 from urllib.parse import urlencode params = {'name': 'germey','age': '22' } base_url = 'http://www.baidu.com?' url = base_url + urlencode(params) print(url)

    運行結(jié)果:

    http://www.baidu.com?name=germey&age=22


  • parse_qs()、parse_qsl()

    parse_qs:反序列化,將get請求參數(shù)轉(zhuǎn)化為字典

    parse_qsl:反序列化,將get參數(shù)轉(zhuǎn)化為元組組成的字典

    # 2.14 parse模塊中parse_qs和parse_qsl方法的使用 from urllib.parse import parse_qs, parse_qsl# 反序列化,將參數(shù)轉(zhuǎn)化為字典類型 query = 'name=germey&age=22' print(parse_qs(query))# 反序列化,將參數(shù)轉(zhuǎn)化為元組組成的列表 print(parse_qsl(query))

    運行結(jié)果:

    {'name': ['germey'], 'age': ['22']} [('name', 'germey'), ('age', '22')]


  • quote()、unquote()

    quote:將內(nèi)容轉(zhuǎn)化為URL編碼的格式,URL中帶有中文參數(shù)時,有可能會導(dǎo)致亂碼的問題,用這個方法就可以將中文字符轉(zhuǎn)化為URL編碼。

    unquote:和quote()方法相反,將URL解碼

    # 2.15 parse模塊中quote()方法和unquote()方法的使用 from urllib.parse import quote, unquotekeyword = '書包' url = 'https://www.baidu.com/?wd=' + quote(keyword) print(url)url = 'https://www.baidu.com/?wd=%E5%A3%81%E7%BA%B8' print(unquote(url))

    運行結(jié)果:

    https://www.baidu.com/?wd=%E4%B9%A6%E5%8C%85 https://www.baidu.com/?wd=壁紙

urllib中的robotparse模塊可以實現(xiàn)robots協(xié)議的分析,用得不多,這里就不再介紹。



2.2 requests庫的使用(重點)

學(xué)習(xí)爬蟲,最基礎(chǔ)的便是模擬瀏覽器向服務(wù)器發(fā)出請求。

requests文檔


2.2.1. requests庫的介紹

利用Python現(xiàn)有的庫可以非常方便的實現(xiàn)網(wǎng)絡(luò)請求的模擬,常見的有urllib、requests等。requests模塊是Python原生的一款基于網(wǎng)絡(luò)請求的模塊,功能非常強大,效率極高。

作用:模擬瀏覽器發(fā)起請求


2.2.2 requests庫的安裝

requests庫是Python的第三方庫,需要額外安裝,在cmd中輸入以下代碼使用pip安裝:

pip install requests


2.2.3 requests庫的使用

要檢查是否已經(jīng)正確安裝requests庫,在編輯器或Python自帶的IDLE中導(dǎo)入requests庫:

import requests

執(zhí)行后沒有發(fā)生錯誤就說明你已經(jīng)正確安裝了requests庫。

也可以在cmd命令行窗口中輸入:

pip list

后按回車,就會顯示所有pip已安裝的第三方庫,在列表中看到request庫就表明成功安裝requests庫。


下面介紹Requests庫的7個主要方法:

方法介紹
requests.request()構(gòu)造一個請求,支撐以下的各種基礎(chǔ)方法,不常用
requests.get()獲取HTML網(wǎng)頁的主要方法,對應(yīng)于HTTP的GET,常用
requests.head()獲取HTML網(wǎng)頁頭信息的方法,對應(yīng)于HTTP的
requests.post()向HTML頁面提交POST請求的方法,對應(yīng)于HTTP的POST
requests.put()向HTM頁面提交PUT請求的方法,對應(yīng)于HTTP的PUT
requests.patch()向HTML頁面提交局部修改請求,對應(yīng)于HTTP的PATCH
requests.delete()向HTML頁面提交刪除請求,對應(yīng)于HTTP的DELETE

2.2.3.1 requests.get()方法

requests.get(url, params=None, **kwargs)

  • url : 要獲取頁面的url鏈接,必選
  • params :url中的額外參數(shù),字典或字節(jié)流格式,可選
  • **kwargs : 12個控制訪問的參數(shù),可選

我們在瀏覽器中輸入一個url后按下enter,其實是發(fā)起一個get請求。同樣,使用requests庫發(fā)起一個get請求,可以使用requests庫下的get()方法,requests.get()方法可以構(gòu)造一個向服務(wù)器請求資源的Request對象并返回一個包含服務(wù)器資源的Response對象。request對象和response對象是requests庫中的2個重要對象,response對象包含服務(wù)器返回的所有信息,也包含請求的request信息,下面是response對象的屬性:

屬性說明
r.status_codeHTTP請求的返回狀態(tài),200表示成功,404表示失敗
r.textHTTP響應(yīng)內(nèi)容的字符串形式,即url對應(yīng)的頁面內(nèi)容
r.encoding從HTTP header中猜測的響應(yīng)內(nèi)容編碼方式,如果header中不存在charset,則認為編碼為ISO-8859-1,r.text根據(jù)r.encoding顯示網(wǎng)頁內(nèi)容
r.apparent_encoding從內(nèi)容中分析出的響應(yīng)內(nèi)容的編碼方式(備用編碼方式,一般比較準確)
r.contentHTTP響應(yīng)內(nèi)容的二進制形式

下面是一個使用requests.get()方法訪問百度并打印出返回的response對象的各種屬性的例子:

import requests# 2.16 使用requests.get()方法發(fā)送一個get()請求 r = requests.get("https://www.baidu.com") print("r的狀態(tài)碼為:", r.status_code) print("r的內(nèi)容為:", r.text) print("從r的header中推測的響應(yīng)內(nèi)容的編碼方式為:", r.encoding) print("從r的內(nèi)容中分析出來的響應(yīng)內(nèi)容編碼方式為:", r.apparent_encoding) print("r內(nèi)容的二進制形式為:", r.content)

2.2.3.2 requests.request()方法

requests.request(method, url, **kwargs)

  • method : 請求方式,對應(yīng)get/put/post/head/patch/delete/options7種
  • url : 要獲取頁面的url鏈接
  • **kwargs : 控制訪問的參數(shù),共13個

**kwargs:控制訪問的參數(shù),都為可選項:

控制訪問參數(shù)說明
params字典或字節(jié)序列,作為參數(shù)增加到url中
data字典、字節(jié)序列或文件對象,作為request的內(nèi)容
jsonJSON格式的數(shù)據(jù),作為request的內(nèi)容
headers字典,HTTP定制頭
cookies字典或cookieJar,Request中的cookie
auth元組,支持HTTP認證功能
files字典類型,傳輸文件
timeout設(shè)置超時時間,秒為單位
proxies字典類型,設(shè)置代理服務(wù)器,可以增加登錄認證
allow_redirectsTrue/False,默認為True,重定向開關(guān)
streamTrue/False,默認為True,獲取內(nèi)容立即下載開關(guān)
verifyTrue/False,默認為True,認證SSL證書開關(guān)
cert本地SSL證書路徑

下面只介紹幾個常用的參數(shù)。


params:字典或字節(jié)序列,作為參數(shù)增加到url中

import requests# 2.17 請求參數(shù)params參數(shù)的使用 kv = {"key1": "value1", "key2": "value2"} r = requests.request('GET', 'http://httpbin.org/get', params=kv) # 也可寫成: r = requests.get('http://httpbin.org/get', params=kv) print(r.url) print(r.text)

如果向網(wǎng)站http://httpbin.org/get發(fā)起一個get請求,該網(wǎng)站會將你的請求頭的信息返回回來。

print(r.url)將輸出:

http://httpbin.org/get?key1=value1&key2=value2,

可以看到,已經(jīng)將字典作為參數(shù)增加到url中了!

同時上面的代碼print(r.text)也將請求放回的信息也打印出來了:

{
“args”: {
“key1”: “value1”,
“key2”: “value2”
},
“headers”: {
“Accept”: “/”,
“Accept-Encoding”: “gzip, deflate”,
“Host”: “httpbin.org”,
“User-Agent”: “python-requests/2.24.0”,
“X-Amzn-Trace-Id”: “Root=1-600f8cf4-6af557655f1c1a771135e7fb”
},
“origin”: “117.150.137.110”,
“url”: “http://httpbin.org/get?key1=value1&key2=value2”
}

上面就是我們發(fā)起的請求的相關(guān)信息,有請求頭、發(fā)起請求的瀏覽器、參數(shù)等。


data:字典、字節(jié)序列或文件對象,作為request的內(nèi)容

import requests# 2.18 請求參數(shù)data的使用 data = 'data' r = requests.request('POST', 'http://httpbin.org/post', data=data) # 也可寫成: r = requests.post('http://httpbin.org/post', data=data) # 這發(fā)起的是POST請求,可以看3.4 print(r.text)

我執(zhí)行后的結(jié)果:

{
“args”: {},
“data”: “data”,
“files”: {},
“form”: {},
“headers”: {
“Accept”: “/”,
“Accept-Encoding”: “gzip, deflate”,
“Content-Length”: “4”,
“Host”: “httpbin.org”,
“User-Agent”: “python-requests/2.24.0”,
“X-Amzn-Trace-Id”: “Root=1-600f8f3d-46564aa85b91258f2d1c7511”
},
“json”: null,
“origin”: “117.150.137.110”,
“url”: “http://httpbin.org/post”
}

可以看到,"data"已經(jīng)作為request的內(nèi)容了。


json:JSON格式的數(shù)據(jù),作為request的內(nèi)容

import requests# 2.19 請求參數(shù)json的使用 kv = {'key1':'value1'} r = requests.request('POST', 'http://httpbin.org/post', json=kv) # 也可寫成:r = requests.post('http://httpbin.org/post', json=kv) print(r.text)

我執(zhí)行后的結(jié)果:

{
“args”: {},
“data”: “{“key1”: “value1”}”,
“files”: {},
“form”: {},
“headers”: {
“Accept”: “/”,
“Accept-Encoding”: “gzip, deflate”,
“Content-Length”: “18”,
“Content-Type”: “application/json”,
“Host”: “httpbin.org”,
“User-Agent”: “python-requests/2.24.0”,
“X-Amzn-Trace-Id”: “Root=1-600f8f00-2419855b4f772b4851c12cdd”
},
“json”: {
“key1”: “value1”
},
“origin”: “117.150.137.110”,
“url”: “http://httpbin.org/post”
}


headers:字典、HTTP定制頭

請求頭Headers提供了關(guān)于請求、響應(yīng)或其他發(fā)送實體的信息。對于爬蟲而言,請求頭非常重要,有很多網(wǎng)站會通過檢查請求頭來判斷請求是不是爬蟲發(fā)起的。

那如何找到正確的Headers呢?

在Chrome中或其他瀏覽器打開要請求的網(wǎng)頁,右擊網(wǎng)頁任意處,在彈出的菜單中單擊“檢查"選項,
點擊Network,點擊下面的資源列表中的任意一個,我點擊的是第一個,在右邊彈出的界面中找到Requests Headers,就可以看到Requests Headers中的詳細信息:

我們將Requests Headers中的user-agent對應(yīng)的信息復(fù)制下來,用在下面的代碼中:

import requests# 2.20 請求參數(shù)headers的使用 headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'} r = requests.request('POST', 'http://httpbin.org/post',headers=headers) # 也可寫成: r = requests.post('http://httpbin.org/post',headers=headers) print(r.text)

我的運行結(jié)果:

{
“args”: {},
“data”: “”,
“files”: {},
“form”: {},
“headers”: {
“Accept”: “/”,
“Accept-Encoding”: “gzip, deflate”,
“Content-Length”: “0”,
“Host”: “httpbin.org”,
“User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36”,
“X-Amzn-Trace-Id”: “Root=1-600f9f2f-016953bc4635251a20212054”
},
“json”: null,
“origin”: “117.150.137.110”,
“url”: “http://httpbin.org/post”
}

可以看到,我們的請求頭中的user-Agent已經(jīng)變成我們自己構(gòu)造的了!


timeout:設(shè)置超時時間,秒為單位

import requests# 2.21 請求參數(shù)timeout的使用 r = requests.request('GET', 'http://www.baidu.com', timeout=10) # 也可寫成: r = requests.request('http://www.baidu.com', timeout=10)

proxies:字典類型,設(shè)定訪問代理服務(wù)器,可以增加代理驗證

import requests# 2.22 請求參數(shù)proxies的使用 pxs = {'http': 'http://user:pass@10.11.1:12344''https': 'https://10.10.10.1.12344' } r = requests.request('GET', 'http://www.baidu.com', proxies=pxs) # 也可寫成: r = requests.get('http://www.baidu.com', proxies=pxs)

cookies: 字典或cookieJar,Request中的cookie

首先看一下獲取cookie的過程:

import requests# 2.23 請求參數(shù)cookies的使用 r = requests.request('GET', 'https://www.baidu.com') # 也可寫成: r = requests.get('https://www.baidu.com') print(r.cookies)for key, value in r.cookies.items():print(key + '=' + value)

運行結(jié)果如下:

<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
BDORZ=27315

第一行是直接打印的cookie信息,我們發(fā)現(xiàn)它是RequestCookieJar類型。第二行是遍歷的Cookie的信息。

我們也可以使用Cookie來保持登錄狀態(tài),以登錄百度為例,首先,登錄百度,讓后用上面我教你的方法來獲取Requests Headers中的user-agent和cookie的信息,將它們設(shè)置到Headers中,然后發(fā)送請求:

import requests# 2.24 使用cookies的實例 headers = {'Cookie': 'BIDUPSID=A41FB9F583DE46FF509B8F9443183F5C;\PSTM=1604237803; BAIDUID=A41FB9F583DE46FF6179FBA5503669E3:FG=1;\BDUSS=jdRb3ZMQTR5OX5XYTd1c0J3eUVSWGVlRVgxZ0VlMjRFR3dGMkZZMDlMNWR\3eWRnRVFBQUFBJCQAAAAAABAAAAEAAACzkIz7vfDP~rarMzIxAAAAAAAAAAAAAAAAAA\AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF02AGBdNgBgW;\BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_PS_PSSID=33425_33437_33344_\31253_33284_33398_33459_26350; delPer=0; PSINO=3; BD_HOME=1; BD_UPN=123\14753; BA_HECTOR=2k808k8h0000a18g001g0v9e80r','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, \like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.50' } r = requests.request('GET', "https://www.baidu.com", headers=headers) # 也可以寫成 r = requests.get("https://www.baidu.com", headers=headers) print(r.text)

這樣,我們就實現(xiàn)了用Python模擬登錄到百度了,結(jié)果中包含我們只有登錄百度后才能查看的信息。



2.2.3.3 處理requests庫的異常

在上面的代碼中,r=requests.get(“https://www.baidu.com”),并不是在任何時候都會成功,如果鏈接打錯或訪問的鏈接不存在,則會產(chǎn)生異常。下面列出了常見的異常:

異常說明
requests.ConnectionError網(wǎng)絡(luò)鏈接錯誤,入DNS查詢失敗,拒絕鏈接等
requests.HTTPErrorHTTP錯誤異常
requests.URLRequiredURL缺失異常
requests.TooManyRedirects超過最大重定向次數(shù),產(chǎn)生重定向異常
requests.ConnectionTimeout鏈接遠程服務(wù)器超時異常
requests.Timeout請求URL超時,產(chǎn)生超時異常

處理異常,可以使用requests.raise_for_status()方法,該方法在其內(nèi)部判斷r.status_code是否等于200,不需要增加額外的if語句:

import requests# 2.25 處理發(fā)送請求過程中的異常 try:# 下面的鏈接錯了,將打印輸出"參數(shù)異常"r = requests.get("https://www.baidu.co")r.raise_for_status()r.encoding = r.apparent_encodingprint(r.text) except:print("產(chǎn)生異常")

2.2.3.4 發(fā)送POST請求

除了GET請求外,有時還需要發(fā)送一些編碼為表單形式的數(shù)據(jù),如在登錄的時候請求就為POST,因為如果使用GET請求,密碼就會顯示在URL中,這是非常不安全的。如果要實現(xiàn)POST請求,其實在上面的介紹requests.request( )方法時就已經(jīng)實現(xiàn)了,你也可以看看下面用requests.post()方法實現(xiàn)的代碼,對比后發(fā)現(xiàn),requests.post()方法其實就是將requests.request(‘POST’, …)方法給包裝起來了,這也是為什么說requests.request()方法是實現(xiàn)其他方法的基礎(chǔ)了,上面的例子中也建議大家不用requests.request()方法。

import requests# 2.26 發(fā)送POST請求 key_dict = {'key1':'value1', 'key2': 'value2'} r = requests.post('http://httpbin.org/post', data=key_dict) # 也可寫成: r = requests.request('POST', 'http://httpbin.org/post', data=key_dict) print(r.text)

按照上面的requests.request()方法的13個訪問參數(shù),你就會將其應(yīng)用到requests.get()或requests.post()方法中了吧!在來看一個例子:

import requestsr = requests.get('http://www.baidu.con', timeout=3) print(r.text)

2.2.3.5 requests庫的使用實例:TOP250電影數(shù)據(jù)、抓取二進制數(shù)據(jù)

打開豆瓣電影TOP250的網(wǎng)站,右鍵鼠標,使用“檢查"功能查看該網(wǎng)頁的請求頭:

按照下面提取請求頭中的重要信息:

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.50','Host': 'movie.douban.com' }

使用這個headers構(gòu)造請求頭并爬取前25個電影的名稱,提取部分的代碼大家看不懂沒關(guān)系,大家只要看懂請求發(fā)起代碼的實現(xiàn):

import requests from bs4 import BeautifulSoup# 2.27 發(fā)送get請求爬取豆瓣電影的前25個電影 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.50','Host': 'movie.douban.com' } r = requests.get('https://movie.douban.com/top250', headers=headers, timeout=10) try:r.raise_for_status()soup = BeautifulSoup(r.text, 'html.parser')movies = soup.find_all('div', {'class': 'hd'})for each in movies:print(each.a.span.text.strip()) except:print("error")

執(zhí)行后將輸出:

肖申克的救贖
霸王別姬
阿甘正傳
這個殺手不太冷

下面是一個抓取favicon.ico圖標的例子:

import requests# 2.28 發(fā)送get請求爬取圖片 r = requests.get('https://github.com/favicon.ico') with open('favicon.ico', 'wb') as f:f.write(r.content)

運行結(jié)束后,文件夾中將出現(xiàn)名為favicon.ico的圖標。上面的代碼先使用get方法發(fā)起一個get請求,讓后將請求返回的內(nèi)容以wb(二進制)寫入favicon.ico文件中。


2.3 正則表達式(重點)



2.3.1 正則表達式的介紹

本節(jié)中,我們看一下正則表達式的相關(guān)用法。正則表達式是處理字符串的強大工具,它有自己特定的語法結(jié)構(gòu),有了它,實現(xiàn)字符串的檢索、替換、匹配驗證都不在話下。

正則表達式是用來簡介表達一組字符串的表達式,正則表達式是一種通用的字符串表達框架。正則表達式可以用來判斷某字符串的特征歸屬。

在爬蟲中,我們使用它來從HTML中提取想要的信息就非常方便了。

例如:正則表達式:

p(Y|YT|YTH|YTHO)?N

它可以表示:

  • ‘PN’
  • ‘PYN’
  • ‘PYTN’
  • ‘PYTHN’
  • ‘PYTHON’

這5個字符串。

正則表達式語法由字符和操作符構(gòu)成,上面的例子中的() | ? 都是操作符,其他的是字符。


下面是正則表達式的常用的操作符:

操作符說明實例
.表示任何單個字符,除了換行符
[ ]字符集,對單個字符給出取值范圍[abc]表示a、b、c,[a-z]表示a到z單個字符
[^ ]非字符集,對單個字符給出排除范圍[^abc]表示非a非b非c的單個字符
*前一個字符0次或無限次擴展abc*表示ab、abc、abcc、abccc等
+前一個字符1次或無限次擴展abc+表示abc、abcc、abccc等
前一個字符0次或1次擴展abc?表示ab、abc
|左右表達式中任意一個abc|def表示abc、def
{m}擴展前一個字符m次ab{2}c表示abbc
{m, n}擴展前一個字符m至n次(含n)ab{1,2}c表示abc、abbc
^匹配字符串開頭^abc表示abc且在一個字符串的開頭
$匹配字符串結(jié)尾abc$表示abc且在一個字符的結(jié)尾
( )分組標記,內(nèi)部只能使用|操作符(abc)表示abc,(abc|def)表示abc、def
\d數(shù)字,等價于[0-9]
\D匹配非數(shù)字
\w匹配非特殊字符,即a-z、A-Z、0-9、_、漢字
\W匹配特殊字符,即非字母、非數(shù)字、非漢字、非_
\n匹配一個換行符
\s匹配空白
\S匹配非空白

正則表達式語法實例:

正則表達式對應(yīng)字符串
p(Y|YT|YTH|YTHO)?N‘PN’,‘PYN’,‘PYTN’,‘PYTHN’,‘PYTHON’
PYTHON+‘PYTHON’,‘PYTHONN’,‘PYTHONNN’ …
PY[TH]ON‘PYTON’,‘PYHON’
PY[^TH]?ON‘PYON’,‘PYaON’,‘PYbON’,‘PYcON’ …
PY{ : 3}N‘PN’,‘PYN’,‘PYYN’、‘PYYYN’

經(jīng)典正則表達式實例:

正則表達式對應(yīng)字符串
^[A-Za-z]+$由26個字母組成的字符串
^[A-Za-z0-9]+$由26個字母和數(shù)字組成的字符串
^\d+$整數(shù)形式的字符串
^[0-9]*[1-9][0-9]*$正整數(shù)形式的字符串
[1-9]\d{5}中國境內(nèi)的郵政編碼,6位
[\u4e00-\u9fa5]匹配中文字符
\d{3}-\d{8}|\d{4}-\d{7}國內(nèi)電話號碼,010-68913536
\d+.\d+.\d+.\d+. 或 \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}匹配IP地址的字符串

其實正則表達式不是Python僅有的,它也出現(xiàn)在其他的編程語言中,只不過語法可能有一點不同。Python中的re庫提供了整個正則表達式的實現(xiàn),下面就來介紹re庫。


2.3.2 Re庫


2.3.2.1 Re庫的介紹

Re庫是Python的標準庫,主要用于字符串匹配。

re文檔

python中的re庫文檔


2.3.2.2 Re庫的使用

要使用Re庫,必須先安裝re庫:

pip install re


re庫的主要功能函數(shù)

函數(shù)說明
re.match()從一個字符串的開始位置起匹配正則表達式
re.search()在一個字符串中搜索匹配正則表達式的第一個位置
re.findall()搜索字符串,以列表類型返回全部能匹配的字符串
re.sub()在一個字符串中替換所有匹配正則表達式的子串,返回替換后的字符串

2.3.2.2.1 re.match()方法

re.match(pattern, string, flags=0)

  • pattern:正則表達式(可以是字符串或原生字符串)
  • string:待匹配字符串
  • flags:正則表達式使用時的控制標記(可選)

? 常見的控制標記

常用標記說明
re.I re.IGNORECASE忽略正則表達式的大小寫,[A-Z]能夠匹配小寫字符
re.M re.MULTILTNE正則表達式中的^操作符能夠?qū)⒔o定字符串的每一行當(dāng)做匹配開始
re.S re.DOTALL正則表達式中的.操作符能夠匹配所有的字符,默認匹配除換行符以外的所有字符

match()方法會嘗試從字符串的起始位置匹配正則表達式,如果匹配,就返回匹配成功的結(jié)果,否則,返回None:

import re# 2.29 re.match()方法的使用 content = 'dfs 234 d 3 34' result = re.match('..', content) print(type(result)) print(result) print(result.group()) print(result.span())

下面是執(zhí)行結(jié)果:

<class 're.Match'> <re.Match object; span=(0, 2), match='df'> df (0, 2)

從結(jié)果可以看出,re.match()方法返回一個re.Match對象,該對象有兩種常用的方法:

  • group():匹配結(jié)果的內(nèi)容,如果有分組,則分組是從1開始的,group[1]表示第一個分組,group[2]表示第二個分組,以此類推。
  • span():輸出匹配到的字符串在原字符串中的起始位置,上面的(0,2)中的0和2就代表了df在’dfs 234 d 3 34’中的起始位置。

正則表達式…匹配到的字符串是df。



2.3.2.2.2 使用分組

上面的例子中,我們用match()方法匹配到了我們想要的字符串,但是,如果我們想要的字符串在匹配結(jié)果中該怎么辦?

例如:

# 2.30 使用分組() import recontent = 'a1234567atsea' result = re.match('a\d{7}a', content) print(result) print(result.group()) print(result.span())

我們要在content中將數(shù)字提取出來,我們發(fā)現(xiàn)數(shù)字都包含在a這個字母中間,所以用a\\d{7}a這個正則表達式來提取,\d表示任意一個數(shù)字,再用{7}將\d(任意一個數(shù)字)匹配7個,運行結(jié)果如下:

a1234567a (0, 9)

我么發(fā)現(xiàn)匹配結(jié)果中開頭和結(jié)尾都包含了一個a,如何只得到1234567能,我們只需要使用分組,并將上面的代碼修改一下就行了:

import re# 2.31 分組()的使用 content = 'a1234567atsea' result = re.match('a(\d{7})a', content) print(result.group()) print(result.span()) print(result.group(1))

運行結(jié)果如下:

a1234567a (0, 9) 1234567

將正則表達式中的\d{7}的兩邊加上小括號,將其作為一個分組,在匹配結(jié)果中使用group(1)將分組取出,可以看到,我們想要的1234567就在匹配結(jié)果中的第一個分組中了(group(1))。



2.3.2.2.3 通用匹配和匹配操作符

在使用正則表達式的時候,要熟練使用.*(通用匹配),其中,.可以匹配任意一個字符,*(星)代表匹配前面的字符無限次,所以它們組合在一起就可以匹配任意字符了(換行符除外)。

下面來看一個通用匹配(.*)的例子:

import re# 2.32 通用匹配(.*)的使用 content = 'rtgfga1234567atsea' result = re.match('.*(\d{7}).*', content) print(result.group()) print(result.span()) print(result.group(1))

運行結(jié)果如下:

rtgfga1234567atsea (0, 18) 1234567

上面的例子中,我們使用了.*來匹配數(shù)字前的任意字符串和數(shù)字之后的任意字符串,在使用分組獲得 我們想要的數(shù)字。

有時候,我們要匹配的字符中包括操作符該怎么辦?可以使用\來將操作符轉(zhuǎn)義,請看下面的例子:

import re# 2.33 在正則表達式中使用轉(zhuǎn)義符 content = '12df www.baidu.com df' result = re.match('12df\s(www\.baidu\.com)\sdf', content) print(result.group()) print(result.span()) print(result.group(1))

在content中,我們要提取www.baidu.com,其中的.是操作符,在寫正則表達式時,我們不能用.來匹配. 因為.代表任意一個字符,我們用\來將其轉(zhuǎn)義,就可以用\.來匹配點了。運行結(jié)果如下:

12df www.baidu.com df (0, 21) www.baidu.com

2.3.2.2.4 貪婪與非貪婪

由于.*代表任意字符串,這就有一個問題,例如:

import re# 2.34 貪婪模式 content = 'dfadas1234567assedf' result = re.match('df.*(\d+).*df', content) print(result.group()) print(result.span()) print(result.group(1))

運行結(jié)果如下:

dfadas1234567assedf (0, 19) 7

(\d+)分組只匹配到了7這一個數(shù)字,我們想要匹配1234567,這是為什么?

這就涉及到了貪婪與非貪婪,由于.*可以匹配任意長度的字符串,所以.*就盡可能的的匹配較多的字符,于是,它就匹配了adas123456,而只讓\d+只匹配到一個7。

貪婪:讓.*匹配盡可能多的字符

非貪婪:讓.*匹配盡可能少的字符

默認.*是貪婪的,要讓.*是非貪婪的,只需要在.*的后面加上?,即:.*?

知道如何將.*設(shè)置為非貪婪模式后,我們就可以將上面的代碼改為如下的代碼:

import re# 2.35 非貪婪模式 content = 'dfadas1234567assedf' result = re.match('df.*?(\d+).*?df', content) print(result.group()) print(result.span()) print(result.group(1))

運行結(jié)果如下:

dfadas1234567assedf (0, 19) 1234567

這就匹配到了我們想要的1234567了。



2.3.2.2.5 控制標記

正則表達式可以包含一些可選標志修飾符來控制匹配的模式,常見的控制標記大家可以看上面介紹re.match()方法中列出的控制標記表格。

下面的代碼中,我們?nèi)稳皇翘崛∽址械乃袛?shù)字:

import recontent = 'dfadas1234567assedf' result = re.match('^df.*?(\d+).*?df$', content) print(result.group()) print(result.span()) print(result.group(1))

運行結(jié)果如下:

dfadas1234567assedf (0, 19) 1234567

我們成功將字符串中的所有數(shù)字提取出來了,但是,我將content修改一下:

import recontent = '''dfadas1234567assedf''' result = re.match('^df.*?(\d+).*?df$', content) print(result.group()) print(result.span()) print(result.group(1))

再運行:

Traceback (most recent call last):File "E:/pycharmWorkStation/venv/Include/draft/test.py", line 6, in <module>print(result.group()) AttributeError: 'NoneType' object has no attribute 'group'Process finished with exit code 1

發(fā)現(xiàn)出錯了!原因是.匹配任意一個除了換行符之外的任意字符,所以.*?匹配到換行符就不能匹配了,導(dǎo)致我們沒有匹配到任何字符,放回結(jié)果為None,而在第6行,我們調(diào)用了None的group()方法。

要修正這個錯誤,我們只需要添加一個re.S控制標記,這個標記的作用是使.匹配任意一個包括換行符在內(nèi)的字符。

import re# 2.36 控制標記的使用 content = '''dfadas1234567assedf''' result = re.match('^df.*?(\d+).*?df$', content, re.S) print(result.group()) print(result.span()) print(result.group(1))

運行結(jié)果如下:

dfadas1234567assedf (0, 30) 1234567

這個re.S控制標記在網(wǎng)頁匹配中經(jīng)常用到。因為HTMl節(jié)點經(jīng)常會換行,加上它,就可以匹配節(jié)點與節(jié)點中的換行了。



2.3.2.2.6 re.search()

上面講的match()方法是從字符串的開頭開始匹配的,一旦開頭就不能匹配,就會導(dǎo)致匹配的失敗,請看下面的例子:

import re# 2.37 re.match()方法是從頭開始匹配的 content = 'df colle 123' result = re.match('colle\s123', content) print(result.group()) print(result.span())

運行結(jié)果出錯,沒有匹配到結(jié)果,返回的是None,None對象沒有g(shù)roup()方法。

re.search():在匹配時掃描整個字符串,讓后返回成功匹配的第一個結(jié)果,如果搜索完了還未找到匹配的,就返回None。也就是說,正則表達式可以是字符串的一部分

import re# 2.38 re.search()方法的使用 content = 'df colle 123' result = re.search('colle\s123', content) print(result.group()) print(result.span())

運行結(jié)果:

colle 123 (3, 12)

2.3.2.2.7 re.findall()

上面所講到的search()方法可以返回匹配到的第一個內(nèi)容,如果我們想要得到所有匹配到的結(jié)果就可以使用findall()方法。

re.findall():搜索字符串,以列表類型返回全部能匹配的子串

import re# 2.39 re.findall()方法的使用 content = 'df colle 123 colle 123' result = re.findall('colle\s123', content) print(result)

運行結(jié)果:

['colle 123', 'colle 123']

2.3.2.2.8 re.sub()

re.sub():將文本中所以匹配的內(nèi)容替換為指定的文本

import re# 2.40 re.sub()方法的使用 content = 'dfcolle123colle123' content = re.sub('\d', '', content) print(content)

運行結(jié)果:

dfcollecolle

上面的代碼中,我們將content中所有與\d(任意一個數(shù)字)匹配的結(jié)果替換為’ ',就去掉了content中所有的數(shù)字。



2.3.2.2.9 re.compile()

re.compile():將正則字符串編譯成正則表達式對象,可以用來復(fù)用。

import re# 2.41 re.compile()方法的使用 content1 = 'dfcolle123colle123' content2 = 'sdf123e' content3 = 'ss23dsfd'pattern = re.compile('\d')content1 = re.sub(pattern, '', content1) content2 = re.sub(pattern, '', content2) content3 = re.sub(pattern, '', content3) print(content1,' ',content2,' ',content3)

代碼中,我們將’\d‘編譯為一個正則表達式對象,并在下面的代碼中將它復(fù)用。

運行結(jié)果:

dfcollecolle sdfe ssdsfd

2.3.3 使用Re來爬取tx視頻

下面來使用re來獲取tx視頻主頁中的所有鏈接和排行榜中所有的電影名稱。

打開tx視頻的主頁,右擊,“檢查”,選擇“元素”:

隨便找到一個鏈接,例如我在圖中畫出來的,根據(jù)它寫出匹配所有連接的正則表達式:

'"((https|http)://.*?)"'

按照如下的圖示來獲取請求的URL、user-Agent、cookie


重新回到“元素”:

按照如下操作獲取排行榜中電影所在的元素:

重復(fù)上面的操作,多獲取幾個排行榜中電影名所在的元素:

例如:

<span class="rank_title">有翡</span> <span class="rank_title">我的小確幸</span> <span class="rank_title">我就是這般女子</span>

根據(jù)它寫出提取排行榜電影名稱的正則表達式為:

‘<span\sclass=“rank_title”>(.*?)’

根據(jù)上面步驟得出的信息可以寫出如下代碼:

import re import requests# 2.42 使用re爬取騰訊視頻的小例子 url = "https://v.qq.com/" # 要爬取的鏈接 headers = { # 構(gòu)造請求頭'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'\' AppleWebKit/537.36 (KHTML, like Gecko) C'\'hrome/88.0.4324.96 Safari/537.36 Edg/88.0.'\'705.53','cookie': 'pgv_pvi=2265568256; pgv_pvid=1230518102; tvfe'\'_boss_uuid=19b8c4da4cc7e833; ts_uid=9797476283'\'; ts_refer=www.baidu.com/link; RK=VGQx4w/ntj; '\'ptcz=fe2dbdf4d8d7efb795bfdc0deaa0429286aa73e0dd'\'444a9173fe43fc7b145a1e; ptag=www_baidu_com; ad_pl'\'ay_index=77; pgv_info=ssid=s5748488123; ts_last=v.'\'qq.com/; bucket_id=9231006; video_guid=8b478b9f33d3db'\'89; video_platform=2; qv_als=cyHwW4MZHa8e9NWRA1161181'\'1694iJW+zw==', } proxy={ # 代理"HTTP": "113.3.152.88:8118","HTTPS":"219.234.5.128:3128", }r = requests.get(url=url, headers=headers, proxies=proxy, timeout=3) # 傳入url、headers、proxies、timeout構(gòu)造get請求 print("狀態(tài)碼為:", r.status_code) # 打印狀態(tài)碼 r.encoding = r.apparent_encoding # 將編碼方式設(shè)置為備用編碼方式pattern = re.compile('"((https|http)://.*?)"', re.S) # 使用re來獲取所有的鏈接,并打印前5個 links = re.findall(pattern, r.text) print("鏈接個數(shù)為:", len(links)) for i in range(5):print(links[i][0])pattern1 = re.compile('<span\sclass="rank_title">(.*?)</span>', re.S) # 使用re來獲取排行榜中所有的電影名稱并 movies = re.findall(pattern1, r.text)print() # 將排行榜中的所有電影名稱打印出來 for i in movies:print(i)

當(dāng)然,這是我的代碼,大家可以將其中的cookie、user-agent和proxy替換為自己的。

運行結(jié)果如下:

狀態(tài)碼為: 200 鏈接個數(shù)為: 1331 http://m.v.qq.com/index.html?ptag= https://puui.qpic.cn/vupload/0/common_logo_square.png/0 http://www.w3.org/2000/svg https://v.qq.com/ https://film.qq.com/有翡 我的小確幸 我就是這般女子 暗戀橘生淮南 這個世界不看臉 山海情[原聲版] 陀槍師姐2021[普通話版] 黑白禁區(qū) 大秦賦 陳情令 長安伏妖 詭婳狐 除暴 赤狐書生 有匪·破雪斬 蜘蛛俠:平行宇宙 重案行動之搗毒任務(wù) 武動乾坤:九重符塔 昆侖神宮 絕對忠誠之國家利益 哈哈哈哈哈 王牌對王牌 第6季 歡樂喜劇人 第7季 我就是演員 第3季 平行時空遇見你 現(xiàn)在就告白 第4季 你好生活 第2季 非常完美 乘風(fēng)破浪的姐姐slay全場 天賜的聲音 第2季 斗羅大陸 開心錘錘 狐妖小紅娘 雪鷹領(lǐng)主 武神主宰 靈劍尊 豬屁登 萬界仙蹤

當(dāng)然,這是我的運行結(jié)果,大家的運行結(jié)果可能和我不一樣,因為排行榜是會變化的。

總結(jié)

以上是生活随笔為你收集整理的Python爬虫基本库的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。