任務預覽(2天)
1. 學習get與post請求,嘗試使用requests或者是urllib用get方法向https://www.baidu.com/發出一個請求,並將其返回結果輸出。
# 此代碼是使用requests庫向百度發出請求
import requests
def main():
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ''(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
response = requests.get('https://www.baidu.com/', headers=HEADERS)
response.encoding = 'utf-8'
print(response.status_code)
if __name__ == '__main__':
main()
2.如果是斷開了網絡,再發出申請,結果又是什麼。瞭解申請返回的狀態碼。
斷網時的結果:
狀態碼 | 說明 | 詳情 |
---|---|---|
100 | 繼續 | 請求者應當繼續提出請求。服務器已收到請求的一部分,正在等待其餘部分。 |
101 | 切換協議 | 請求者已要求服務器切換協議,服務器已確認並準備切換。 |
200 | 成功 | 服務器已成功處理了請求。 |
201 | 已創建 | 請求成功並且服務器創建了新的資源。 |
202 | 已接受 | 服務器已接受請求,但尚未處理。 |
203 | 非授權信息 | 服務器已成功處理了請求,但返回的信息可能來自另一個來源。 |
204 | 無內容 | 服務器成功處理了請求,但沒有返回任何內容。 |
205 | 重置內容 | 服務器成功處理了請求,內容被重置。 |
206 | 部分內容 | 服務器成功處理了部分請求。 |
300 | 多種選擇 | 針對請求,服務器可執行多種操作。 |
301 | 永久移動 | 請求的網頁已永久移動到新位置,即永久重定向。 |
302 | 臨時移動 | 請求的網頁暫時跳轉到其他頁面,即暫時重定向。 |
303 | 查看其他位置 | 如果原來的請求是POST,重定向目標文檔應該通過GET提取。 |
304 | 未修改 | 此次請求返回的網頁未修改,繼續使用上次的資源。 |
305 | 使用代理 | 請求者應該使用代理訪問該網頁。 |
307 | 臨時重定向 | 請求的資源臨時從其他位置相應。 |
400 | 錯誤請求 | 服務器無法解析該請求。 |
401 | 未授權 | 請求沒有進行身份驗證或驗證未通過。 |
403 | 禁止訪問 | 服務器拒絕此請求。 |
404 | 未找到 | 服務器找不到請求的網頁。 |
405 | 方法禁用 | 服務器禁用了請求中指定的方法。 |
406 | 不接受 | 無法使用請求的內容響應請求的網頁。 |
407 | 需要代理授權 | 請求者需要使用代理授權。 |
408 | 請求超時 | 服務器請求超時。 |
409 | 衝突 | 服務器在完成請求時發生衝突。 |
410 | 已刪除 | 請求的資源已永久刪除。 |
411 | 需要有效長度 | 服務器不接受不含有效內容長度標頭字段的請求。 |
412 | 爲滿足前提條件 | 服務器未滿足請求者在請求中設置的其中一個前提條件。 |
413 | 請求實體過大 | 請求實體過大,超出服務器的處理能力。 |
414 | 請求URI過長 | 請求網址過長,服務器無法處理。 |
415 | 不支持類型 | 請求的格式不受請求頁面的支持。 |
416 | 請求範圍不符 | 頁面無法提供請求的範圍。 |
417 | 未滿足期望值 | 服務器未滿足期望請求標頭字段的要求。 |
500 | 服務器內部錯誤 | 服務器遇到錯誤,無法完成請求。 |
501 | 未實現 | 服務器不具備完成請求的功能。 |
502 | 錯誤網關 | 服務器作爲網關或代理,從上游服務器收到無效響應。 |
503 | 服務不可用 | 服務器目前無法使用。 |
504 | 網關超時 | 服務器作爲網關或代理,但是沒有及時從上游服務器收到請求。 |
505 | HTTP版本不支持 | 服務器不支持請求中所用的 HTTP 協議版本。 |
3.瞭解什麼是請求頭,如何添加請求頭。
請求頭,用來說明服務器要使用的附加信息,比較重要的信息有Cookie、Referer、User-Agent等,下面將一些常用的頭信息說明如下:
- Accept:請求報頭域,用於指定客戶端可接受哪些類型的信息。
- Accept-Language:指定客戶端可接受的語言類型。
- Accept-Encoding:指定客戶端可接受的內容編碼。
- Host:用於指定請求資源的主機 IP 和端口號,其內容爲請求 URL 的原始服務器或網關的位置。從 HTTP 1.1 版本開始,Request 必須包含此內容。
- Cookie:也常用複數形式 Cookies,是網站爲了辨別用戶進行 Session 跟蹤而儲存在用戶本地的數據。Cookies 的主要功能就是維持當前訪問會話,例如我們輸入用戶名密碼登錄了某個網站,登錄成功之後服務器會用 Session 保存我們的登錄狀態信息,後面我們每次刷新或請求該站點的其他頁面時會發現都是保持着登錄狀態的,在這裏就是 Cookies 的功勞,Cookies 裏有信息標識了我們所對應的服務器的 Session 會話,每次瀏覽器在請求該站點的頁面時都會在請求頭中加上 Cookies 並將其發送給服務器,服務器通過 Cookies 識別出是我們自己,並且查出當前狀態是登錄的狀態,所以返回的結果就是登錄之後才能看到的網頁內容。
- Referer,此內容用來標識這個請求是從哪個頁面發過來的,服務器可以拿到這一信息並做相應的處理,如做來源統計、做防盜鏈處理等。
- User-Agent,簡稱 UA,它是一個特殊字符串頭,使得服務器能夠識別客戶使用的操作系統及版本、瀏覽器及版本等信息。在做爬蟲時加上此信息可以僞裝爲瀏覽器,如果不加很可能會被識別出爲爬蟲。
- Content-Type,即 Internet Media Type,互聯網媒體類型,也叫做 MIME 類型,在 HTTP 協議消息頭中,使用它來表示具體請求中的媒體類型信息。
'''
添加請求頭
'''
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ''(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
response = requests.get(url, headers=HEADERS)
4.學習什麼是正則表達式並嘗試一些正則表達式並進行匹配。
正則表達式(regular expression)描述了一種字符串匹配的模式(pattern),可以用來檢查一個串是否含有某種子串、將匹配的子串替換或者從某個串中取出符合某個條件的子串等。
正則表達式測試工具:http://tool.oschina.net/regex/
匹配規則:
模式 | 描述 |
---|---|
\w | 匹配字母數字及下劃線 |
\W | 匹配非字母數字及下劃線 |
\s | 匹配任意空白字符,等價於 [\t\n\r\f]. |
\S | 匹配任意非空字符 |
\d | 匹配任意數字,等價於 [0-9] |
\D | 匹配任意非數字 |
\A | 匹配字符串開始 |
\Z | 匹配字符串結束,如果是存在換行,只匹配到換行前的結束字符串 |
\z | 匹配字符串結束 |
\G | 匹配最後匹配完成的位置 |
\n | 匹配一個換行符 |
\t | 匹配一個製表符 |
^ | 匹配字符串的開頭 |
$ | 匹配字符串的末尾 |
. | 匹配任意字符,除了換行符,當 re.DOTALL 標記被指定時,則可以匹配包括換行符的任意字符 |
[… | ] |
[^…] | 不在 [] 中的字符:abc 匹配除了 a,b,c 之外的字符。 |
* | 匹配 0 個或多個的表達式。 |
+ | 匹配 1 個或多個的表達式。 |
? | 匹配 0 個或 1 個由前面的正則表達式定義的片段,非貪婪方式 |
{n} | 精確匹配 n 個前面表達式。 |
{n, m} | 匹配 n 到 m 次由前面的正則表達式定義的片段,貪婪方式 |
a b |
匹配 a 或 b |
( ) | 匹配括號內的表達式,也表示一個組 |
Python中使用正則表達式要import re
# 導入正則表達式的re庫
import re
5.結合requests、re兩者的內容爬取https://movie.douban.com/top250裏的內容。6.要求抓取名次、影片名稱、國家、導演等字段。
第一頁的網址:
第二頁網址:
不難看出規律:start等於0+(頁碼-1)*25
我們寫2個函數,一個get_html(url):通過url獲取網頁信息,一個get_info(html):通過網頁信息,利用正則表達式來篩選出想要的信息。
第一步導包:
import requests
import re
寫第一個get_html(url)函數:
def get_html(url):
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ''(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
response = requests.get(url, headers=HEADERS)
response.encoding = 'utf-8'
if response.status_code == 200:
return response.text
return None
這是我們要篩選的信息,現在我們通過正則表達式進行篩選。
第二個def get_info(html)函數:
def get_info(html):
pattern = re.compile(
r'<li.*?<em class="">(.*?)</em>.*?<span.*?title">(.*?)</span>.*?<p.*?>.*?導演: (.*?); (.*?)<br>(.*?) / (.*?) / (.*?)</p>.*?</li>',
re.S)
items = re.findall(pattern, html)
for item in items:
yield {
'index': item[0],
'movie_name': item[1],
'country': item[5],
'director': item[2]
}
再寫主函數:
if __name__ == '__main__':
for i in range(10):
url = 'https://movie.douban.com/top250?start=%d&filter=' % (i*25)
html = get_html(url)
for item in get_info(html):
print(item)
全部代碼:
import requests
import re
def get_html(url):
HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 ''(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
response = requests.get(url, headers=HEADERS)
response.encoding = 'utf-8'
if response.status_code == 200:
return response.text
return None
def get_info(html):
pattern = re.compile(
r'<li.*?<em class="">(.*?)</em>.*?<span.*?title">(.*?)</span>.*?<p.*?>.*?導演: (.*?); (.*?)<br>(.*?) / (.*?) / (.*?)</p>.*?</li>',
re.S)
items = re.findall(pattern, html)
for item in items:
yield {
'index': item[0],
'movie_name': item[1],
'country': item[5],
'director': item[2]
}
if __name__ == '__main__':
for i in range(10):
url = 'https://movie.douban.com/top250?start=%d&filter=' % (i*25)
html = get_html(url)
for item in get_info(html):
print(item)