一. urllib庫
urllib是Python自帶的一個用於爬蟲的庫,其主要作用就是可以通過代碼模擬瀏覽器發送請求。其常被用到的子模塊在Python3中的為urllib.request和urllib.parse,在Python2中就是urllib和urllib2。
二.requests庫
- 安裝: pip install requests
- 作用: 就是用來模擬瀏覽器上網的
- 特點: 簡單高效
- 使用流程:
* 指定url
* 發起請求
* 獲取響應數據
* 持久化存儲
三.爬取簡單的網頁
普通get請求
1 # 爬取搜狗首頁的頁面數據 2 import requests 3 # 第一步指定url 4 url = 'https://www.sogou.com/' 5 # 第二步發送請求 6 response = request.get(url=url) 7 # 第三步獲取響應數據 8 page_text = response.text #text返回的是字符串類型的數據(由響應體中的content-type,也可以是json) 9 # 第四步持久化存儲 10 with open('./souhu.html','w',encoding='utf-8') as fp: 11 fp.write(page_text) 12 13 print('搜狗首頁爬取完畢!!!')
普通post請求
請求載體身份標識的偽裝:
-
-
User-Agent:請求載體身份標識,通過瀏覽器發起的請求,請求載體為瀏覽器,則該請求的User-Agent為瀏覽器的身份標識,使用爬蟲程序發起的請求,則該請求的載體為爬蟲程序,則該請求的User-Agent為爬蟲程序的身份標識。可以通過判斷該值來獲知該請求的載體究竟是基於哪款瀏覽器還是基於爬蟲程序。
-
反爬機制:某些門戶網站會對訪問該網站的請求中的User-Agent進行捕獲和判斷,如果該請求的UA為爬蟲程序,則拒絕向該請求提供數據。
-
反反爬策略:將爬蟲程序的UA偽裝成某一款瀏覽器的身份標識
-
# 普通post請求
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)
ajax的post請求:
- 爬取肯德基任意城市的位置信息
1 #爬取任意城市對應的肯德基餐廳的位置信息 2 #動態加載的數據 3 city = input('enter a cityName:') 4 url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword' 5 data = { 6 "cname": "", 7 "pid": "", 8 "keyword": city, 9 "pageIndex": "2", 10 "pageSize": "10", 11 } 12 #UA偽裝 13 headers = { 14 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' 15 } 16 response = requests.post(url=url,headers=headers,data=data) 17 18 json_text = response.text 19 20 print(json_text)
普通post請求
- 爬取百度翻譯輸入任意內容翻譯出來的結果
1 #破解百度翻譯 2 url = 'https://fanyi.baidu.com/sug' 3 word = input('enter a English word:') 4 #請求參數的封裝 5 data = { 6 'kw':word 7 } 8 #UA偽裝 9 headers = { 10 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' 11 } 12 response = requests.post(url=url,data=data,headers=headers) 13 #text:字符串 json():對象 14 obj_json = response.json() 15 16 print(obj_json)
ajax的get請求
需求:爬取豆瓣電影分類排行榜 https://movie.douban.com/中的電影詳情數據
1 import requests 2 import urllib.request 3 if __name__ == "__main__": 4 5 #指定ajax-get請求的url(通過抓包進行獲取) 6 url = 'https://movie.douban.com/j/chart/top_list?' 7 8 #定制請求頭信息,相關的頭信息必須封裝在字典結構中 9 headers = { 10 #定制請求頭中的User-Agent參數,當然也可以定制請求頭中其他的參數 11 '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', 12 } 13 14 #定制get請求攜帶的參數(從抓包工具中獲取) 15 param = { 16 'type':'5', 17 'interval_id':'100:90', 18 'action':'', 19 'start':'0', 20 'limit':'20' 21 } 22 #發起get請求,獲取響應對象 23 response = requests.get(url=url,headers=headers,params=param) 24 25 #獲取響應內容:響應內容為json串 26 print(response.text)
四. 爬取較難的數據
- 步驟分析:
1. 通過抓包工具檢測出首頁中的企業信息數據全部為動態加載
2. 通過抓包工具獲取了動態加載數據對應的ajax的數據包(url,請求參數)
3. 通過對步驟2的url請求后獲取的響應數據中分析出有一個特殊的字段ID(每家企業都有一個唯一的ID值)
4. 從手動點擊企業進入企業的詳情頁,發現瀏覽器地址欄中的url中包含了該企業的ID,使用企業ID和固定的域名可以拼接成詳情頁的url
5. 發現詳情頁的企業詳情信息對應的數據值是動態加載出來的。上述我們獲取詳情頁的url是無用的。
6. 通過抓包工具的全局搜索的功能,可以定位到企業詳情信息對應的ajax數據包(url,請求參數),對應的響應數據就是最終我們想要爬取的企業詳情數據。
1 # http://125.35.6.84:81/xk/ 爬取每家企業的企業詳情數據 2 3 import requests 4 headers = { 5 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' 6 } 7 first_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList' 8 ids = [] 9 for page in range(1,11): 10 data = { 11 "on": "true", 12 "page": str(page), 13 "pageSize": "15", 14 "productName": "", 15 "conditionType": "1", 16 "applyname": "", 17 "applysn": "", 18 } 19 response = requests.post(url=first_url,data=data,headers=headers) 20 #response.headers返回的是響應頭信息(字典) 21 if response.headers['Content-Type'] == 'application/json;charset=UTF-8': 22 json_obj = response.json() 23 for dic in json_obj['list']: 24 ids.append(dic['ID']) 25 26 detail_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById' 27 for _id in ids: 28 data = { 29 'id':_id 30 } 31 company_text = requests.post(detail_url,data=data,headers=headers).text 32 print(company_text)
五 . 補充踩過的坑:
get請求參數有 url params headers
post請求參數 url data headers
使用urllib爬取數據請參考:https://www.cnblogs.com/bobo-zhang/p/9646634.html