Python爬虫日记2——使用requests
1基本用法
import requestsurl = 'https://www.baidu.com/' r = requests.get(url) print(type(r)) print(r.status_code) print(type(r.text)) print(r.text) print(r.cookies) """ 調用get()方法,輸出response的類型、狀態碼、響應體的類型、響應內容以及cookies r.text # 返回響應內容 """r.text,網頁返回內容是str類型,如要直接解析返回結果,得到一個字典格式的話,可直接調用json()方法。r.json()
1.1添加參數
---snip--- data = {'name': 'germey','age': 22 } r = requests.get(url, params=data) # 利用params參數1.2抓取網頁
import requests import reheaders = {'User-Agent': 'Mozilla/5.0 (Macintosh; Inter Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36' } r = requests.get("https://www.zhihu.com/explore", headers=headers) pattern = re.compile('explore-feed.*?question_link.*?>(.*?)</a>', re.S) title = re.findall(pattern, r.text) print(title) """ 輸出結果就一個[],問題還未解決 """1.3抓取二進制數據,抓取圖片
圖片、音頻、視頻這些文件本質上都是由二進制碼組成,想要抓取他們,就要拿到他們的二進制碼。
import requestsr = requests.get("https://g.alicdn.com/tb/login/0.4.7/weibo/css/images/ico-taobao.png") # print(r.text) # print(r.content) with open('taobao.png', 'wb') as f:f.write(r.content)GET 請求頁面,并返回頁面內容
POST 大多用于提交表單或上傳文件,數據包含在請求體中
1.4PSOT請求,并寫入文件
import requestsdata = {'name': 'germey', 'age': '22'} r = requests.post('http://httpbin.org/post', data=data) print(type(r.text)) print(type(r.content)) with open('filename.txt', 'w') as f:f.write(r.text) with open('filename2.txt', 'wb') as f:f.write(r.content)""" <class 'str'> <class 'bytes'> r.text 返回響應類型為str,r.content返回響應類型為bytes with open('filename.txt', 'wb') as f: # 用open()方法,他的第一個參數是文件名稱,第二個參數代表以二進制寫的形式打開,可以向文件里寫入二進制數據。 """1.5requests內置的狀態碼查詢對象requests.codes
import requestsr = requests.get('https://www.jianshu.com') exit() if not r.status_code == requests.codes.ok else print('Request Successfully')2高級用法
2.1上傳文件
import requestsfiles = {'file': open('favicon.ico', 'rb')} # 這是一個字典,file為鍵,:后面為值 r = requests.post('http://httpbin.org/post', files=files) # requests模擬提交數據 print(r.text)(讀取文件)下面的程序打開并讀取文件,再將其內容顯示到屏幕上:
with open('wenjian.txt') as file: contents = file.read() print(contents)2.2Cookies
用requests可以輕松處理cookies,這里以news.baidu.com為例
import requestsr = requests.get('http://news.baidu.com') print(r.cookies) # 調用cookies屬性,便可得到Cookies。運行發現它是一個RequestsCookieJar類型 for key, value in r.cookies.items(): # items()方法將其轉換為元組組成的列表,遍歷每一個Cookies的名稱和值,實現Cookies的遍歷解析。print(key + '=' + value)2.3 用Cookies來維持登錄狀態
這里測試失敗,后期補充
2.3.1 會話維持
Session() 對象,維持一個會話
import requestsrequests.get('http://httpbin.org/cookies/set/number/123456789') r = requests.get('http://httpbin.org/cookies') print(r.text)s = requests.Session() # 創建一個實例 s.get('http://httpbin.org/cookies/set/number/123456789') r = s.get('http://httpbin.org/cookies') print(r.text)2.4 SSL證書驗證
通常verify參數默認設置為True,如果證書驗證錯誤導致訪問失敗,可以把vertify設置為False。但是會產生警告
r = requests.get(url, vertify=False)
設置忽視警告
import urllib3
urllib3.disable_warnings()
或者捕獲警告到日志
import logging
logging.captureWarnings(True)
2.5 代理設置
import requestsurl = 'http://...' proxies = {"http": "http://user:password@host:port" } r = requests.get(url, proxies=proxies)2.6 超時設置
timeout()
import requestsr = requests.get('https://www.baidu.com', timeout=1) print(r.status_code) """ timeout=1 # 這個設置將用作連接和讀取的timeout總和 timeout=(5,1) # 設置一個元組,分別指示連接和讀取的時間 如果想要永久等待,可以將timeout的值設置為None,或者不設置直接留空,默認是None """2.7 身份認證
訪問網站時,有時會遇到身份認證頁面,此時可以使用requests自帶的身份認證功能:
import requests from requests.auth import HTTPBasicAuthr = requests.get('http://localhost:5000', auth=HTTPBasicAuth('username', 'password')) print(r.status_code) """ 如果密碼和用戶名正確,會返回200;如果認證失敗,返回401。 """ """ 出錯未解決:[WinError 10061] 由于目標計算機積極拒絕,無法連接。 """3 正則表達式,re庫,match()方法
開源中國提供的正則表達式測試工具https://tool.oschina.net/regex/
Python的re庫提供了整個正則表達式的實現。
3.1 實例
一個常用的匹配方法一match (),向它傳人要匹配的字符串以及正表達式即可檢測。
在 match ()方法中,第一個參數傳入了正則表達式,第二個參數傳入了要匹配的字符串
3.2 match(),通用匹配.*
match()方法會嘗試從字符串的起始位置匹配正則表達式,如果匹配,就返回匹配成功的結果;如果不匹配,就返回None
匹配目標:使用()括號將想要的子字符串括起來
import recontent = 'Hello 1234567 World_This is a Regex Demo' print(len(content)) result = re.match('^Hello\s(\d+)\s(\w{5})', content) # 使用()括號將想要提取的子字符串括起來,()標記了一個子表達式的開始和結束位置 print(result) print(result.group()) print(result.group(1)) # 調用group(1)來獲得匹配結果 print(result.group(2)) print(result.span()) """ 40 <re.Match object; span=(0, 19), match='Hello 1234567 World'> Hello 1234567 World 1234567 World (0, 19) """3.2.1 非貪婪匹配 .*?
貪婪匹配是盡可能匹配多的字符,非貪婪匹配是盡可能匹配少的字符
字符串中間盡量使用非貪婪匹配,即用.*?來代替.*,以,避免匹配缺少
字符串結尾盡量使用.*,以避免匹配不到結果
3.2.2 修飾符 re.S, re.I
. 匹配的是除換行符之外的任意字符,當遇到換行符時,.*? 就不能匹配了,所以導致匹配失敗,這里只需加一個修飾符 re.S ,即可修正。
import recontent = '''Hello 1234567 World_This is a Regex Demo ''' print(len(content)) result = re.match('^He.*?(\d+).*?Demo$', content, re.S) # 使用()括號將想要提取的子字符串括起來,()標記了一個子表達式的開始和結束位置 print(result) print(result.group(1)) print(result.span()) # .*通用匹配 # .*?非貪婪匹配 # re.S 使.匹配包括換行符在內的所有字符3.2.3 轉義匹配
當遇到用于正則匹配模式的特殊字符時,在前面加反斜線轉義一下即可。
3.3 searach()
方法search (),它在匹配時會掃描整個字符串,然后返回第一個成功匹配的結 。即正則表達式可以是字符串的一部分,在匹配時,search ()方法會依次掃描字符串,直到找到第一個符合規則的字符串,然后返回匹配內容,如果搜索完了還沒有找到,就返回 None。
**search()**方法只返回匹配正則表達式的第一個內容
3.4 findall()
search()方法可以返回匹配正則表達式的第一個內容,findall()可以獲取匹配正則表達式的所有內容。
findall()方法,如果有返回結果,則結果是列表類型,可以遍歷列表獲取每組內容。
3.5 sub()
修改文本
import recontent = '54gfgfdsg56dsag' content = re.sub('\d+', '', content) # 第一個參數\d+來匹配所有的數字,第二個參數為替換成的字符串(去掉參數的話,賦值為空),第三個參數是原字符串 print(content)3.6 compile()
compile()將正則表達式編譯成一個正則表達式對象,以便復用
爬取貓眼電影名稱
import requests import redef get_one_page(url):headers = {'User_Agent': 'Mozilla/5.0 (Macintosh; Inter Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'} # 設置代理服務器response = requests.get(url, headers=headers)if response.status_code == 200:response.encoding = 'utf8' # 如果不加這條語句,輸出爬取的信息為亂碼!# 爬取下來的編碼是ISO-8859-1格式,需要轉化為utf-8格式,加一句response.encoding = “utf8”return response.textreturn Nonedef parse_one_page(html):pattern = re.compile('<head>.*?>(.*?)<', re.S)items = re.findall(pattern, html)print(items)with open('filename.txt', 'w') as f:f.write(str(items))def main():url = 'http://maoyan.com/board/4'html = get_one_page(url)print(html)parse_one_page(html)main()# 在network的response中查看原始請求得到的源碼 """ 1、一部電影信息對應的源代碼是一個dd節點,排名信息在class為borad-index的i節點內,利用非貪婪模式來提取i節點內的信息,正則表達式:<dd>.*?board-index.*?>(.*?)</i> 2、提取電影的圖片,在a節點后,其內部有兩個img節點,第二個img節點的data-src屬性是圖片的鏈接,提取這個屬性,正則表達式:<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)" 3、提取電影的名稱,在p節點后,class為name,正則表達式:<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a> 4、提取其他內容方法類似 """爬取小說《靈武封神》第一章
小點:findall()和search()的區別
import requests import redef get_one_page(url):headers = {'User_Agent': 'Mozilla/5.0 (Macintosh; Inter Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'} # 設置代理服務器response = requests.get(url, headers=headers)if response.status_code == 200:response.encoding = 'utf8' # 如果不加這條語句,輸出爬取的信息為亂碼!# 爬取下來的編碼是ISO-8859-1格式,需要轉化為utf-8格式,加一句response.encoding = “utf8”return response.textreturn Nonedef parse_one_page(html):pattern = re.compile('<title>(.*?)</title>', re.S)items = re.findall(pattern, html) # findall()匹配的是正則表達式()里的內容,如果有返回結果的話,就是列表類型。有(),則只返回()里的內容;沒有(),則返回正則表達式的內容。# items = re.search(pattern, html) # search()匹配的是正則表達式的內容print(items)with open('filename.txt', 'w') as f:f.write(str(items))def main():url = 'http://book.zongheng.com/chapter/891033/58356325.html'html = get_one_page(url)print(html)parse_one_page(html)if __name__ == '__main__':# __name__是內置變量,可用于表示當前模塊的名字# if __name__=='__main__'下的代碼只能被自己直接執行,不能被其他程序import調用執行;main()# 在network的response中查看原始請求得到的源碼參考書籍《Python 3網絡開發爬蟲實戰》
總結
以上是生活随笔為你收集整理的Python爬虫日记2——使用requests的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 早安,娜娜。(全本完结)
- 下一篇: led灯珠型号及使用参数