想爬蟲?登錄了再說

作者 | 蘇克1900

來源 | 第2大腦

摘要: 在進行爬蟲時,除了常見的不用登錄就能爬取的網站,還有一類需要先登錄的網站。比如豆瓣、知乎,以及上一篇文章中的桔子網。這一類網站又可以分爲:只需輸入帳號密碼、除了帳號密碼還需輸入或點擊驗證碼等類型。本文以只需輸入賬號密碼就能登錄的桔子網爲例,介紹模擬登錄常用的 3 種方法。

  • POST 請求方法:需要在後臺獲取登錄的 URL並填寫請求體參數,然後 POST 請求登錄,相對麻煩;
  • 添加 Cookies 方法:先登錄將獲取到的 Cookies 加入 Headers 中,最後用 GET 方法請求登錄,這種最爲方便;
  • Selenium 模擬登錄:代替手工操作,自動完成賬號和密碼的輸入,簡單但速度比較慢。

下面,我們用代碼分別實現上述 3 種方法。

1. 目標網頁

這是我們要獲取內容的網頁:

http://radar.itjuzi.com/investevent

這個網頁需要先登錄才能看到數據信息,登錄界面如下:

可以看到,只需要輸入賬號和密碼就可以登錄,不用輸驗證碼,比較簡單。下面我們利用一個測試賬號和密碼,來實現模擬登錄。

2. POST 提交請求登錄

首先,我們要找到 POST 請求的 URL。

有兩種方法,第一種是在網頁 devtools 查看請求,第二種是在 Fiddler 軟件中查看。

先說第一種方法。

在登錄界面輸入賬號密碼,並打開開發者工具,清空所有請求,接着點擊登錄按鈕,這時便會看到有大量請求產生。哪一個纔是 POST 請求的 URL呢?這個需要一點經驗,因爲是登錄,所以可以嘗試點擊帶有 「login」字眼的請求。這裏我們點擊第四個請求,在右側 Headers 中可以看到請求的 URL,請求方式是 POST類型,說明 URL 找對了。

接着,我們下拉到 Form Data,這裏有幾個參數,包括 identify 和 password,這兩個參數正是我們登錄時需要輸入的賬號和密碼,也就是 POST 請求需要攜帶的參數。

參數構造非常簡單,接下來只需要利用 Requests.post 方法請求登錄網站,然後就可以爬取內容了。

下面,我們嘗試用 Fiddler 獲取 POST 請求。

如果你對 Fiddler 還不太熟悉或者沒有電腦上沒有安裝,可以先了解和安裝一下。

Fiddler 是位於客戶端和服務器端的 HTTP 代理,也是目前最常用的 HTTP 抓包工具之一 。 它能夠記錄客戶端和服務器之間的所有 HTTP 請求,可以針對特定的 HTTP 請求,分析請求數據、設置斷點、調試 web 應用、修改請求的數據,甚至可以修改服務器返回的數據,功能非常強大,是 web 調試的利器。

Fiddler 下載地址:

https://www.telerik.com/download/fiddler

使用教程:

https://zhuanlan.zhihu.com/p/37374178

http://www.hangge.com/blog/cache/detail_1697.html

下面,我們就通過 Fiddler 截取登錄請求。

當點擊登錄時,官場 Fiddler 頁面,左側可以看到抓取了大量請求。通過觀察,第15個請求的 URL中含有「login」字段,很有可能是登錄的 POST 請求。我們點擊該請求,回到右側,分別點擊「inspectors」、「Headers」,可以看到就是 POST 請求,該 URL 和上面的方法獲取的 URL 是一致的。

接着,切換到右側的 Webforms 選項,可以看到 Body 請求體。也和上面方法中得到的一致。

獲取到 URL 和請求體參數之後,下面就可以開始用 Requests.post 方法模擬登錄了。

代碼如下:

 1import requests
 2headers = {
 3    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
 4    }
 5data = {
 6    'identity':'[email protected]',   
 7    'password':'test2018',
 8}
 9url ='https://www.itjuzi.com/user/login?redirect=&flag=&radar_coupon='
10session = requests.Session()
11session.post(url,headers = headers,data = data)
12# 登錄後,我們需要獲取另一個網頁中的內容
13response = session.get('http://radar.itjuzi.com/investevent',headers = headers)
14print(response.status_code)
15print(response.text)

使用 session.post 方法提交登錄請求,然後用 session.get 方法請求目標網頁,並輸出 HTML代碼。可以看到,成功獲取到了網頁內容。

下面,介紹第 2 種方法。

3. 獲取 Cookies,直接請求登錄

上面一種方法,我們需要去後臺獲取 POST 請求鏈接和參數,比較麻煩。下面,我們可以嘗試先登錄,獲取 Cookie,然後將該 Cookie 添加到 Headers 中去,然後用 GET 方法請求即可,過程簡單很多。

代碼如下:

 1import requests
 2headers = {
 3    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',
 4    'Cookie': '你的cookie',
 5}
 6url = 'https://www.itjuzi.com/user/login?redirect=&flag=&radar_coupon='
 7session = requests.Session()
 8response = session.get('http://radar.itjuzi.com/investevent', headers=headers)
 9
10print(response.status_code)
11print(response.text)

可以看到,添加了 Cookie 後就不用再 POST 請求了,直接 GET 請求目標網頁即可。可以看到,也能成功獲取到網頁內容。

下面介紹第 3 種方法。

4. Selenium 模擬登錄

這個方法很直接,利用 Selenium 代替手動方法去自動輸入賬號密碼然後登錄就行了。

關於 Selenium 的使用,在之前的一篇文章中有詳細介紹,如果你不熟悉可以回顧一下:

Python爬蟲(6):Selenium 爬取東方財富網上市公司財務報表

代碼如下:

 1from selenium import webdriver
 2from selenium.webdriver.common.by import By
 3from selenium.webdriver.support import expected_conditions as EC
 4from selenium.webdriver.support.wait import WebDriverWait
 5browser = webdriver.Chrome()
 6browser.maximize_window()  # 最大化窗口
 7wait = WebDriverWait(browser, 10) # 等待加載10s
 8
 9def login():
10    browser.get('https://www.itjuzi.com/user/login')
11    input = wait.until(EC.presence_of_element_located(
12        (By.XPATH, '//*[@id="create_account_email"]')))
13    input.send_keys('[email protected]')
14    input = wait.until(EC.presence_of_element_located(
15        (By.XPATH, '//*[@id="create_account_password"]')))
16    input.send_keys('test2018')
17    submit = wait.until(EC.element_to_be_clickable(
18        (By.XPATH, '//*[@id="login_btn"]')))
19    submit.click() # 點擊登錄按鈕
20    get_page_index()
21
22def get_page_index():
23    browser.get('http://radar.itjuzi.com/investevent')
24    try:
25        print(browser.page_source)  # 輸出網頁源碼
26    except Exception as e:
27        print(str(e))
28login()

這裏,我們在網頁中首先定位了賬號節點位置:'//*[@id="create_account_email"]',然後用 input.send_keys 方法輸入賬號,同理,定位密碼框位置並輸入密碼。接着定位 登錄 按鈕的位置://*[@id="login_btn"],然後用 submit.click() 方法實現點擊登錄按鈕操作,從而完成登錄。可以看到,也能成功獲取到網頁內容。

以上就是模擬需登錄網站的幾種方法。當登錄進去後,就可以開始爬取所需內容了。

源代碼可以在下面鏈接中獲得:

https://github.com/makcyun/web_scraping_with_python

5. 總結:

  • 本文分別實現了模擬登錄的 3 種操作方法,建議優先選擇第 2 種,即先獲取 Cookies 再 Get 請求直接登錄的方法。
  • 本文模擬登錄的網站,僅需輸入賬號密碼,不需要獲取相關加密參數,比如 Authenticity_token ,同時也無需輸入驗證碼,所以方法比較簡單。但是還有很多網站模擬登錄時,需要處理加密參數、驗證碼輸入等問題。後續將會介紹。

本文完。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章