1、requests作用:
-
就是一個基於網絡請求的模塊,可以用來模擬瀏覽器發請求。
-
環境安裝:
- pip install requests
-
requests模塊的使用流程:
- 指定一個字符串形式url
- 發起請求
- 獲取響應數據
- 持久化存儲
-
實現一個簡易的網頁采集器
- 爬取到任意關鍵字對應的頁面源碼數據
簡單需求:爬取搜狗首頁的頁面源碼數據
import requests
#指定一個字符串形式url
url = 'https://www.sogou.com/'
#發起請求
response = requests.get(url=url) #get返回一個響應對象
#獲取響應數據
page_text = response.text #獲取字符串形式的響應數據
#持久化存儲
with open('./sougou.html','w',encoding='utf-8') as fp:
fp.write(page_text)
2、案例需求1:實現簡易的網頁采集器,爬取到任意關鍵字對應的頁面源碼數據
2.1過程1分析
import requests
url = 'https://www.sogou.com/web?query=jay'
response = requests.get(url=url)
page_text = response.text
with open('./jay.html','w',encoding='utf-8') as fp:
fp.write(page_text)
上述代碼出現了問題:
- 出現了亂碼問題
- 數據量級不對
2.2過程2分析
#解決亂碼問題
url = 'https://www.sogou.com/web?query=jay'
response = requests.get(url=url)
# response.encoding#返回響應數據原始的編碼格式
response.encoding = 'utf-8'
page_text = response.text
with open('./jay.html','w',encoding='utf-8') as fp:
fp.write(page_text)
- 當前的請求被搜狗認定為是一個異常的請求
- 什么是異常的請求?
- 服務器端檢測到該次請求不是基於瀏覽器訪問。使用爬蟲程序發起的請求就是異常的請求。
- User-Agent:
- 本身是請求頭中的一個信息。
- 概念:請求載體的身份標識
- 請求載體:瀏覽器,爬蟲程序
- 什么是異常的請求?
- 反爬機制:UA檢測
- 對方服務器端會檢測請求載體的身份標識,如果不是基於某一款瀏覽器的身份標識則認定為是一個異常請求,則不會響應會正常的數據。
- 反反爬策略:UA偽裝
- 將爬蟲程序發起的異常的請求載體標識偽裝或者修改成某一款瀏覽器的身份標識即可
2.3正常拿到數據
加上 User-Agent:請求載體的身份標識
url = 'https://www.sogou.com/web?query=jay'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36
'
}
#UA偽裝
response = requests.get(url=url,headers=headers)
# response.encoding#返回響應數據原始的編碼格式
response.encoding = 'utf-8'
page_text = response.text
with open('./jay.html','w',encoding='utf-8') as fp:
fp.write(page_text)
3、參數動態化
- 可以動態的給請求指定請求參數
key = input('enter a key word:')
#將請求參數封裝成鍵值對
params = {
'query':key
}
url = 'https://www.sogou.com/web'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36
'
}
#參數動態化
response = requests.get(url=url,headers=headers,params=params)
# response.encoding#返回響應數據原始的編碼格式
response.encoding = 'utf-8'
page_text = response.text
fileName = key+'.html'
with open(fileName,'w',encoding='utf-8') as fp:
fp.write(page_text)
print(fileName,'爬取成功!!!')
>>>
enter a key word:我的夢
我的夢.html 爬取成功!!!
4、爬取動態加載的數據
- 所謂動態加載的數據是指不是通過瀏覽器地址欄的url請求到的數據。
- 如何檢測我們爬取的數據是否為動態加載的數據?
- 基於抓包工具做局部搜索(在抓包工具中找到地址欄url對應的數據包,在其response這個選項卡下進行搜索爬取數據的關鍵字)
- 如何爬取動態加載的數據?
- 基於抓包工具做全局搜索,可以幫我們定位到動態加載的數據到底是存在於哪一個數據包中,定位到之后,就可以對該數據包的url進行請求發送捕獲數據。
5、案例需求2:爬取豆瓣中前10名電影詳情數據
- 當滾輪向下滑動的時候,會加載出更多的電影數據,說明當滾輪滑動到底部時,會發起一個ajax請求,該次請求會加載出更多的數據。
url = 'https://movie.douban.com/j/chart/top_list'
params = {
'type': '17',
'interval_id': '100:90',
'action': '',
'start': '0',
'limit': '10',
}
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
#json()返回字典或者列表對象
data_list = requests.get(url=url,headers=headers,params=params).json()
for dic in data_list:
title = dic['title']
score = dic['score']
# print('電影名稱:',title,'\t評分:',score)
with open('./movie.txt','a+',encoding='utf-8') as f:
f.write(f'電影名稱:{title} 評分:{score}\n')
fp.close()
輸出到文件中
- 動態加載數據的生成方式:
- ajax請求
- js
- 日后對一個陌生的網站進行數據爬取,在編碼之前必須要做的一件事情是什么?
- 檢測你要爬取的數據是否為動態加載的數據
- 如果不是動態加載數據就可以直接對地址欄的url發起請求爬取數據
- 如果是動態加載數據就需要基於抓包工具進行全局搜索爬取數據
- 檢測你要爬取的數據是否為動態加載的數據
6、案例需求3:將北京所有肯德基餐廳的位置信息進行爬取:
數據爬取地址:http://www.kfc.com.cn/kfccda/storelist/index.aspx
import requests
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
city = input('enter a city name:')
# 獲取3頁數據
for page in range(4):
data = {
'cname': '',
'pid': '',
'keyword': city,
'pageIndex': str(page),
'pageSize': '10',
}
#參數動態化使用的是data參數
data_dict = requests.post(url=url,headers=headers,data=data).json()
for i in data_dict.get('Table1'):
storename = i.get('storeName')
addressDetail = i.get('addressDetail')
filename = 'KFC_address'
with open(f'./{filename}.txt','a+',encoding='utf-8') as f:
f.write(f'店名:{storename},地址:{addressDetail}\n')
f.close()
print(filename,'爬取成功!!!')
>>>
enter a city name:北京
KFC_address 爬取成功!!!
輸出到文件中
7、案例需求4:將所有企業的詳情信息進行爬取保存
數據爬取地址:http://125.35.6.84:81/xk/
分析:
- 嘗試着將某一家企業的詳情數據爬取到,然后再把此操作作用到其他家企業爬取到所有企業的數據。
- 檢測某一家企業詳情數據是否為動態加載的數據
- 基於抓包工具實現局部搜索
- 結論:為動態加載數據
- 基於抓包工具實現局部搜索
- 基於抓包工具進行全局搜索定位動態加載數據的數據包,從數據包中提取url和請求參數
- url:http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById
- 請求方式:post
- 參數:id: ff83aff95c5541cdab5ca6e847514f88
- 通過對比不同企業的詳情數據包的信息,發現請求的url,請求方式都一樣,只有請求參數id的值不一樣而已。
import requests
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'
}
post_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList'
fp = open('company_data.txt','w',encoding='utf-8')
#爬取兩頁數據
for page in range(1,3):
data = {
'on': 'true',
'page': str(page),
'pageSize': '15',
'productName': '',
'conditionType': '1',
'applyname': '',
'applysn':'',
}
json_data = requests.post(url=post_url,headers=headers,data=data).json()
for dic in json_data['list']:
company_id = dic['ID']
url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById'
data = {
'id':company_id
}
detail_json = requests.post(url=url,headers=headers,data=data).json()
per_name = detail_json['businessPerson']
addr = detail_json['epsAddress']
fp.write(f'企業負責人:{per_name},企業住所:{addr}\n')
fp.close()
輸出到文件
8、案例5:圖片數據的爬取
兩種方法:
- urllib
- requests
- urllib和requests的功能作用都幾乎是一致。urllib是一個比較古老的網絡請求模塊,當requests問世后,就快速的替代了urllib。
爬取圖片方式1
url = 'http://gss0.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/3b292df5e0fe99257d8c844b34a85edf8db1712d.jpg'
#content返回二進制類型的響應數據
img_data = requests.get(url=url,headers=headers).content
with open('123.png','wb') as fp:
fp.write(img_data)
爬取圖片方式2
from urllib import request
url = 'http://gss0.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/3b292df5e0fe99257d8c844b34a85edf8db1712d.jpg'
request.urlretrieve(url=url,filename='./456.png')
圖片兩種爬取方式的區別:
- 方式1是可以進行UA偽裝
- 方式2無法進行UA偽裝