瞭解了爬蟲和網絡請求,下面就可以開始正式的瞭解Python中爬蟲相關的模塊了
很多爬蟲相關的書籍一般剛開始都會講一下urllib模塊,等你跟着書中的學完之後,會告訴你urllib模塊用起來比較複雜,通常不使用
確實,urllib是一個比較古老的模塊,封裝的爬蟲方法也相對複雜。所以可以直接開始擼requests
模塊.
Requests模塊的作用就是模擬瀏覽器發送請求。是Python中原生的一款基於網絡請求的模塊,不僅功能強大,而且使用起來也比較簡單!
模塊的安裝
直接通過pip進行安裝即可
pip install requests
使用起來也非常的簡單,分爲三步
- 指定URL,也就是說你要爬取的網站地址
- 發送請求,請求又分爲GET/POST/PUT/DELETE等等
- 獲取響應數據
這樣看是不是非常簡單呢?廢話不多說,來個簡單的例子,比如我需要爬取百度的首頁
GET請求
# 導入模塊
import requests
url = 'https://www.baidu.com'
# 發送get請求
response = requests.get(url)
# 獲取網頁源代碼
baidu_html = response.text
# 將獲取的數據進行持久化(保存)
with open('baidu.html', 'w', encoding='utf-8') as f:
f.write(baidu_html)
執行之後就會在同級目錄下有個baidu.html
的文件。
以上就是一個最最最基本的使用requests發送get請求的例子。同樣如果發送其他請求比如POST/PUT/HEAD等等
requests.post(url)
requests.delete(url)
requests.put(url)
...
在發送請求的時候,大部分時候會攜帶一些參數的。比如我們進行搜索的時候,發送的GET請求就會攜帶搜索內容
比如我在百度上搜索python
時,url是 https://www.baidu.com/s?wd=python
爲了使爬蟲程序更加靈活,肯定要將搜索的內容進行分離。可以通過構建一個字典參數,發送GET請求
import requests
# 輸入搜索的關鍵詞
wd = input('請輸入要搜索的內容:\n')
url = 'https://www.baidu.com/s?'
# 構建get請求的搜索參數
url_param = {'wd': wd}
# 防止爬蟲被攔截,增加請求的UA
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'
}
# 發送GET請求
response = requests.get(url, params=url_param, headers=header)
# 獲取網頁源代碼
wd_html = response.text
# 寫入文件,持久化操作
with open('wd.html', 'w', encoding='utf-8') as f:
f.write(wd_html)
具體的GET用法如下
# url 訪問的地址
# params 攜帶的參數
# **kwargs 其他參數,比如請求頭、cookie、代理(proxies)等等
def get(url, params=None, **kwargs):
POST請求
使用httpbin網站進行測試
httpbin是一個能測試HTTP請求和響應的網站,支持各種請求方法
1、以form表單的形式提交參數,只需要將請求參數構造成一個字典,傳給data參數即可。
import requests
url = 'http://httpbin.org/post'
params = {'name': '公衆號:Python極客專欄', 'language': 'python'}
response = requests.post(url, data=params)
print(response.json())
執行結果:
{
'args': {},
'data': '',
'files': {},
'form': {
'language': 'python',
'name': '公衆號:Python極客專欄'
},
'headers': {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Content-Length': '99',
'Content-Type': 'application/x-www-form-urlencoded',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.22.0',
'X-Amzn-Trace-Id': 'Root=1-5fef5112-65ad78d4706c58475905fef2'
},
'json': None,
'origin': '',
'url': 'http://httpbin.org/post'
}
2、以字符串的形式提交參數,通過json.dumps
將字典轉換成字符串
import requests
import json
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'
}
url = 'http://httpbin.org/post'
params = {'name': 'Tom', 'hobby': ['music', 'game']}
# 通過json.dumps 將字典格式化爲json字符串
response = requests.post(url, json=json.dumps(params), headers=header)
print(response.json())
執行結果:
{
'args': {},
'data': '"{\\"name\\": \\"Tom\\", \\"hobby\\": [\\"music\\", \\"game\\"]}"',
'files': {},
'form': {},
'headers': {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Content-Length': '55',
'Content-Type': 'application/json',
'Host': 'httpbin.org',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36', # 請求中加入的headers在這裏也可以看到
'X-Amzn-Trace-Id': 'Root=1-5fef583e-5224201d08e2ff396416e822'
},
'json': '{"name": "Tom", "hobby": ["music", "game"]}',
'origin': '',
'url': 'http://httpbin.org/post'
}
3、使用post請求提交文件(以multipart形式)
import requests
import json
header = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'
}
url = 'http://httpbin.org/post'
# 讀取 baidu.html 文件, 'rb':以二進制形式讀取
files = {'file': open('baidu.html', 'rb')}
# post形式傳入file文件
response = requests.post(url, files=files)
print(response.json())
執行結果:
{
'args': {},
'data': '',
'files': {
'file': '<!DOCTYPE html>.....此處省略HTML內容...'
},
'form': {},
'headers': {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Content-Length': '2732',
'Content-Type': 'multipart/form-data; boundary=1ba2b1406c4a4fe89c1846dc6398dae5',
'Host': 'httpbin.org',
'User-Agent': 'python-requests/2.22.0',
'X-Amzn-Trace-Id': 'Root=1-5fef58f8-68f9fb2246eb190f06092ffb'
},
'json': None,
'origin': '',
'url': 'http://httpbin.org/post'
}
響應的處理
通過GET/POST等請求會獲取到服務器的響應,也就是上面例子中的response
。改如何獲取更多的信息呢?
import requests
headers = {
'referer': 'https://www.baidu.com',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'
}
url = 'http://httpbin.org/post'
# 讀取 baidu.html 文件, 'rb':以二進制形式讀取
files = {'file': open('baidu.html', 'rb')}
# post形式傳入file文件
response = requests.post(url, files=files, headers=headers, cookies={'test': 'abcdefg'})
# response的處理
# 指定編碼
response.encoding = 'utf-8'
print(response.url) # 請求的url
print(response.encoding) # 請求的編碼、
print(response.status_code) # 狀態碼
print(response.content) # 響應內容的二進制形式 (保存文件、圖片、音頻等)
print(response.text) # 響應內容的文本形式
print(response.json()) # 響應內容的json形式
print(response.headers) # 響應頭信息
print(response.request.headers) # 請求頭信息
print(response.request.headers['referer']) # 請求頭對應屬性的內容
print(response.cookies) # cookie信息,返回的cookie對象
print(response.cookies.items())
輸出結果如下圖