原文javascript
第三方庫 requests是基於urllib編寫的。比urllib庫強大,很是適合爬蟲的編寫。html
安裝: pip install requestsjava
簡單的爬百度首頁的例子:python
response.text 和 response.content的區別:瀏覽器
- response.text是解過碼的字符串。比較容易出現亂碼
- response.content 未解碼的二進制格式(bytes). 適用於文本,圖片和音樂。若是是文本,可使用 response.content.decode('utf-8') 解碼
requests 庫支持的請求方法:服務器
import requests requests.get("http://xxxx.com/") requests.post("http://xxxx.com/post", data = {'key':'value'}) requests.put("http://xxxx.com/put", data = {'key':'value'}) requests.delete("http://xxxx.com/delete") requests.head("http://xxxx.com/get") requests.options("http://xxxx.com/get")
發送帶參數的get 請求:cookie
在get方法裏設置字典格式的params參數便可。requests 方法會自動完成url的拼接session
import requests params = { "wd": "python", "pn": 10, } response = requests.get('https://www.baidu.com/s', params=params) print(response.url) print(response.text)
'''
須要設置header,百度會進行反爬驗證
'''
發送帶數據的post 請求:app
只須要在post方法裏設置data參數便可。 raise_for_status()會表示成功或失敗ecmascript
import requests post_data = {'username': 'value1', 'password': 'value2'} response = requests.post("http://xxx.com/login/", data=post_data) response.raise_for_status()
post 文件的例子:
>>> import requests >>> url = 'http://httpbin.org/post' >>> files = {'file': open('report.xls', 'rb')} >>> r = requests.post(url, files=files)
設置與查看請求頭(headers):
不少網站有反爬機制,若是一個請求不攜帶請求頭headers,極可能被禁止訪問。
import requests headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/" "537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" } response1 =requests.get("https://www.baidu.com", headers=headers) response2 =requests.post("https://www.xxxx.com", data={"key": "value"}, headers=headers) print(response1.headers) print(response1.headers['Content-Type']) print(response2.text)
設置代理Proxy:
有的網站反爬機制會限制單位時間內同一IP的請求次數,咱們能夠經過設置 IP proxy代理來應對這個反爬機制。
import requests proxies = { "http": "http://10.10.1.10:3128", "https": "http://10.10.1.10:1080", } requests.get("http://example.org", proxies=proxies)
Cookie的獲取和添加:
有時候咱們須要爬取登陸後才能訪問的頁面,這時咱們就須要藉助cookie來實現模擬登錄和會話維持了。
當用戶首次發送請求時,服務器端通常會生成並存儲一小段信息,包含在response數據裏。若是這一小段信息存儲在客戶端(瀏覽器或磁盤),咱們稱之爲cookie.若是這一小段信息存儲在服務器端,咱們稱之爲session(會話).這樣當用戶下次發送請求到不一樣頁面時,請求自動會帶上cookie,這樣服務器就制定用戶以前已經登陸訪問過了。
能夠經過打印 response.cookies來獲取查看cookie內容,從而知道首次請求後服務器是否生成了cookie.
發送請求時添加cookie的方法:
- 設置cookies參數
import requests headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/" "537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" } cookies = {"cookie_name": "cookie_value", } response = requests.get("https://www.baidu.com", headers=headers, cookies=cookies)
- 先實例化一個 RequestCookieJar的類,而後把值set進去,最後在get,post方法裏面指定cookie參數
Session會話的維持:
session 與cookie不一樣,由於session通常存儲在服務器端。session對象可以幫咱們跨請求保持某些參數,也會在同一個session實例發出的全部請求之間保持cookies.
爲了保持會話的連續,咱們最好的辦法是先建立一個session對象,用它打開一個url,而不是直接使用 request.get方法打開一個url.
每當咱們使用這個session對象從新打開一個url時,請求頭都會帶上首次產生的cookie,實現了會話的延續。
例子:
爬百度前20條搜索記錄。(結果仍是有點問題的,由於跳轉的太多了,搜出不是對應的大條目)
#coding: utf-8 ''' 爬取百度搜索前20個搜索頁面的標題和連接 ''' import requests import sys from bs4 import BeautifulSoup as bs import re import chardet headers = { 'Accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language':'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest' } def main(keyword): file_name = "{}.txt".format(keyword) f = open(file_name,'w+', encoding='utf-8') f.close() for pn in range(0,20,10): params = {'wd':keyword,'pn':pn} response = requests.get("https://www.baidu.com/s",params=params,headers=headers) soup = bs(response.content,'html.parser') urls = soup.find_all(name='a',attrs={"href": re.compile('.')}) for i in urls: if 'http://www.baidu.com/link?url=' in i.get('href'): a = requests.get(url=i.get('href'),headers=headers) print(i.get('href')) soup1 = bs(a.content,'html.parser') title = soup1.title.string with open(keyword+'.txt','r',encoding='utf-8') as f: if a.url not in f.read(): f = open(keyword+'.txt','a',encoding='utf-8') f.write(title + '\n') f.write(a.url + '\n') f.close() if __name__ == '__main__': keyword ='Django' main(keyword) print("下載完成")