引入
Requests 唯一的一個非轉基因的 Python HTTP 庫,人類可以安全享用。
警告:非專業使用其他 HTTP 庫會導致危險的副作用,包括:安全缺陷症、冗余代碼症、重新發明輪子症、啃文檔症、抑郁、頭疼、甚至死亡。
今日概要
- 基於requests的get請求
- 基於requests模塊的post請求
- 基於requests模塊ajax的get請求
- 基於requests模塊ajax的post請求
- 綜合項目練習:爬取國家葯品監督管理總局中基於中華人民共和國化妝品生產許可證相關數據
知識點回顧
- 常見的請求頭
- 常見的相應頭
- https協議的加密方式
今日詳情
- 基於如下5點展開requests模塊的學習
- 什么是requests模塊
- requests模塊是python中原生的基於網絡請求的模塊,其主要作用是用來模擬瀏覽器發起請求。功能強大,用法簡潔高效。在爬蟲領域中占據着半壁江山的地位。
- 為什么要使用requests模塊
- 因為在使用urllib模塊的時候,會有諸多不便之處,總結如下:
- 手動處理url編碼
- 手動處理post請求參數
- 處理cookie和代理操作繁瑣
- ......
- 使用requests模塊:
- 自動處理url編碼
- 自動處理post請求參數
- 簡化cookie和代理操作
- ......
- 因為在使用urllib模塊的時候,會有諸多不便之處,總結如下:
- 如何使用requests模塊
- 安裝:
- pip install requests
- 使用流程
- 指定url
- 基於requests模塊發起請求
- 獲取響應對象中的數據值
- 持久化存儲
- 安裝:
- 通過5個基於requests模塊的爬蟲項目對該模塊進行學習和鞏固
- 基於requests模塊的get請求
- 需求:爬取搜狗指定詞條搜索后的頁面數據
- 基於requests模塊的post請求
- 需求:破解百度翻譯
- 基於requests模塊ajax的get請求
- 需求:爬取豆瓣電影分類排行榜 https://movie.douban.com/中的電影詳情數據
- 基於requests模塊ajax的post請求
- 需求:爬取肯德基餐廳查詢http://www.kfc.com.cn/kfccda/index.aspx中指定地點的餐廳數據
- 綜合練習
- 需求:爬取國家葯品監督管理總局中基於中華人民共和國化妝品生產許可證相關數據http://125.35.6.84:81/xk/
- 基於requests模塊的get請求
- 代碼展示
需求1:爬取搜狗指定詞條搜索后的頁面數據
import requests import os #指定搜索關鍵字 word = input('enter a word you want to search:') #自定義請求頭信息 headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } #指定url url = 'https://www.sogou.com/web' #封裝get請求參數 prams = { 'query':word, 'ie':'utf-8' } #發起請求 response = requests.get(url=url,params=param) #獲取響應數據 page_text = response.text with open('./sougou.html','w',encoding='utf-8') as fp: fp.write(page_text)
請求載體身份標識的偽裝:
User-Agent:請求載體身份標識,通過瀏覽器發起的請求,請求載體為瀏覽器,則該請求的User-Agent為瀏覽器的身份標識,使用爬蟲程序發起的請求,則該請求的載體為爬蟲程序,則該請求的User-Agent為爬蟲程序的身份標識。可以通過判斷該值來獲知該請求的載體究竟是基於哪款瀏覽器還是基於爬蟲程序。
反爬機制:某些門戶網站會對訪問該網站的請求中的User-Agent進行捕獲和判斷,如果該請求的UA為爬蟲程序,則拒絕向該請求提供數據。
反反爬策略:將爬蟲程序的UA偽裝成某一款瀏覽器的身份標識。
需求2: 破解百度翻譯
# 破解百度翻譯 import requests wd = input("Please input an English word: ") param = { "kw": wd } headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36" } # 1.指定URL url = "https://fanyi.baidu.com/sug" # 2.發送請求 response = requests.post(url=url, data=param, headers=headers) response.encoding = "utf-8" # 3.獲取響應數據 # page_text = response.text # import json # json_obj = json.loads(page_text) json_obj = response.json() print(json_obj) # 4.持久化存儲 # 總結: # 1.使用requests的POST請求方式發送請求,並攜帶參數 # 2.指定響應對象的編碼方式 # 3.在響應對象的數據類型為JSON的前提下,可以使用response.json()方法直接獲取json數據
需求3:登錄豆瓣電影,爬取登錄成功后的頁面數據
import requests import os url = 'https://accounts.douban.com/login' #封裝請求參數 data = { "source": "movie", "redir": "https://movie.douban.com/", "form_email": "15027900535", "form_password": "bobo@15027900535", "login": "登錄", } #自定義請求頭信息 headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } response = requests.post(url=url,data=data) page_text = response.text with open('./douban111.html','w',encoding='utf-8') as fp: fp.write(page_text)
需求4:爬取豆瓣電影分類排行榜 https://movie.douban.com/中的電影詳情數據
#!/usr/bin/env python # -*- coding:utf-8 -*- import requests import urllib.request if __name__ == "__main__": #指定ajax-get請求的url(通過抓包進行獲取) url = 'https://movie.douban.com/j/chart/top_list?' #定制請求頭信息,相關的頭信息必須封裝在字典結構中 headers = { #定制請求頭中的User-Agent參數,當然也可以定制請求頭中其他的參數 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36', } #定制get請求攜帶的參數(從抓包工具中獲取) param = { 'type':'5', 'interval_id':'100:90', 'action':'', 'start':'0', 'limit':'20' } #發起get請求,獲取響應對象 response = requests.get(url=url,headers=headers,params=param) #獲取響應內容:響應內容為json串 print(response.text)
需求5:爬取肯德基餐廳查詢http://www.kfc.com.cn/kfccda/index.aspx中指定地點的餐廳數據
#!/usr/bin/env python # -*- coding:utf-8 -*- import requests import urllib.request if __name__ == "__main__": #指定ajax-post請求的url(通過抓包進行獲取) url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword' #定制請求頭信息,相關的頭信息必須封裝在字典結構中 headers = { #定制請求頭中的User-Agent參數,當然也可以定制請求頭中其他的參數 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36', } #定制post請求攜帶的參數(從抓包工具中獲取) data = { 'cname':'', 'pid':'', 'keyword':'北京', 'pageIndex': '1', 'pageSize': '10' } #發起post請求,獲取響應對象 response = requests.get(url=url,headers=headers,data=data) #獲取響應內容:響應內容為json串 print(response.text)
需求6:爬取國家葯品監督管理總局中基於中華人民共和國化妝品生產許可證相關數據
# 需求:爬取國家葯品監督管理總局中基於中華人民共和國化妝品生產許可證相關數據http://125.35.6.84:81/xk/ # 分析: # 1. 首頁企業名稱列表的數據是通過ajax動態請求獲取到的 # 2. 我們獲取到的首頁企業名稱列表的數據里面有一條ID數據很重要,需要通過這個ID來獲取詳情頁的URL # 3. 企業詳情頁的數據也是通過ajax請求動態獲取到的 # 4. 獲取企業詳情頁的數據發送的請求攜帶的參數就有這個ID值,通過這個請求才能獲取到企業詳情頁的數據 import requests url = "http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36" } enterprise_id_list = list() detail_list = list() for page in range(1,7): datas = { "on": "true", "page": page, "pageSize": "15", "productName": "", "conditionType": "1", "applyname": "", "applysn": "" } obj_json = requests.post(url=url, data=datas, headers=headers).json() for dic in obj_json["list"]: enterprise_id = dic["ID"] enterprise_id_list.append(enterprise_id) # print(enterprise_id_list) detail_post_url = "http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById" for id in enterprise_id_list: post_data = { "id": id } detail_obj_json = requests.post(url=detail_post_url, data=post_data, headers=headers).json() detail_list.append(detail_obj_json) print(len(detail_list)) print(detail_list)
import requests from fake_useragent import UserAgent ua = UserAgent(use_cache_server=False,verify_ssl=False).random headers = { 'User-Agent':ua } url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList' pageNum = 3 for page in range(3,5): data = { 'on': 'true', 'page': str(page), 'pageSize': '15', 'productName':'', 'conditionType': '1', 'applyname':'', 'applysn':'' } json_text = requests.post(url=url,data=data,headers=headers).json() all_id_list = [] for dict in json_text['list']: id = dict['ID']#用於二級頁面數據獲取 #下列詳情信息可以在二級頁面中獲取 # name = dict['EPS_NAME'] # product = dict['PRODUCT_SN'] # man_name = dict['QF_MANAGER_NAME'] # d1 = dict['XC_DATE'] # d2 = dict['XK_DATE'] all_id_list.append(id) #該url是一個ajax的post請求 post_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById' for id in all_id_list: post_data = { 'id':id } response = requests.post(url=post_url,data=post_data,headers=headers) #該請求響應回來的數據有兩個,一個是基於text,一個是基於json的,所以可以根據content-type,來獲取指定的響應數據 if response.headers['Content-Type'] == 'application/json;charset=UTF-8': #print(response.json()) #進行json解析 json_text = response.json() print(json_text['businessPerson'])
作業:
1. 爬取任意城市的肯德基餐廳的位置信息
2. 爬取國家葯品監督管理總局中基於中華人民共和國化妝品生產許可證相關數據http://125.35.6.84:81/xk/
3. 爬取百度貼吧
