python爬蟲登錄豆瓣(二)

之前使用 requests 庫普通登錄了豆瓣,這次爲帶驗證碼登錄。
(故意幾次使用錯誤的帳號和密碼登陸可以出現驗證碼登錄,也因此這次請求時需要提交 cookies,說明之前幾次密碼是錯誤的)
同上一篇的過程一樣,能過 chrome 瀏覽器抓包,提交 header、data以及 cookies。
豆瓣爬蟲2
由於這次需要抓取驗證碼圖片,因此使用了 bs4 庫的 BeautifulSoup 類,同時使用 tkinter 顯示圖片。
tkinter 不支持 png 的圖片,所以將驗證碼又轉化成了字符串形式查看。
剛開始時是將 255 個灰藍值分爲8個區間,分別用 0-8 表示。之後通過實驗,發現驗證碼中的字母顏色比較暗,都在 32 以內,所以直接將 32 灰度值內的像素顯示爲 0,其它用 + 號表示,這樣看得更清楚。
關於圖片轉化字符串可查看之前的博客:

import requests
from bs4 import BeautifulSoup as BS
import tkinter as tk
import tkinter.simpledialog as dl
import re

url = "https://accounts.douban.com/login"
ver_code = None

#注意將帳號和密碼替換爲你自己的帳號和密碼
data = {"source": "None", \
        "redir": "https://www.douban.com",\
         "form_email": "帳號", \
         "form_password": "密碼",\
         "login": "登錄",\
         "captcha-id": "bVR0nvFoEDAuMZ0SPo2g1E8Y:en"}

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36",\
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",\
            "Host": "accounts.douban.com"}
# 關於這裏的 cookies 不需要全部手工輸入,將其複製下來,使用 python 簡單處理爲字典,然後將輸出結果複製在這裏即可。注意這些字符串使用三引號,不然無法處理
cookies = {'ll': '118106', 'push_doumail_num': '0', 'push_noty_num': '0', '_ga': 'GA1.2.1081158021.1474542167', '_gat_UA-7019765-1': '1', 'ap': '1', '__utmz': '30149280.1474731328.5.3.utmcsr', '__utmv': '30149280.12980', '__utmb': '30149280.5.9.1474731328', 'ps': 'y', '__utmt': '1', 'bid': 'QYjV6bR5rKk', '_vwo_uuid_v2': 'CD7AD2F6CEB891B777278E390A20BF60|1a0d32af0452a7a4f362b8f380163bee', 'ue': '[email protected]', '__utmc': '30149280', '__utma': '30149280.1081158021.1474542167.1474644084.1474731328.5'}

# 獲取驗證碼圖片的地址,並返回
def get_src(text):
    bs = BS(r.text, "html.parser")
    div = bs.find('div', {"class": "item item-captcha"})
    img = BS(str(div), "html.parser").find('img')
    return img

# 將驗證碼保存在本地
def save_image(src, file):
    # 圖片爲二進制數據,所有爲 wb 方式打開
    with open("ver.png", "wb") as f:
        ver_r = requests.get(img['src'])
        f.write(ver_r.content)

# 將驗證碼轉化爲字符串形式,以文本形式保存在本地
def image_trans(src, file):
    import PIL.Image as image
    img = image.open(src)
    img = img.convert('L')
    w,h = img.size
    with open(file, 'w') as f:
        for y in range(h):
            line = ''
            for x in range(w):
                line += '0' if img.getpixel((x,y)) // 32 == 0 else '+'
            print(line, file=f)

# 使用 tkinter 將轉換後的驗證碼顯示出來
def get_ver(file):
    ver_text = get_ver_text(file)
    top = tk.Tk()
    ver_label = tk.Label(top, text=ver_text)
    ver_label.pack()
    ver_code = dl.askstring("verification", "請輸入驗證碼")
    return ver_code

# 人工識別驗證碼,並輸入
def get_ver_text(file):
    ver_text= ''````
    with open(file, 'r') as f:
        for line in f:
            ver_text += line
    return ver_text

if __name__ == "__main__"
    # 先請求登錄的界面
    r = requests.post(url, headers=headers, cookies=cookies)
    with open("0.html", "w") as f:
        print(r.text, file=f)
    img = get_src(r.text)
    save_image(img['src'], "ver.png")
    image_trans("ver.png", "ver.txt")
    ver_code = get_ver("ver.txt")
    print(ver_code)

    # 將驗證碼添加至要提交的數據中 
    data.update({"captcha-solution": ver_code})
    # 添加 Referer 至頭部
    headers.update({"Referer": "https://accounts.douban.com/login:"})
    # 帶驗證碼再次提交請求
    r = requests.post(url, data=data, headers=headers, cookies=cookies)
    # 將最終抓取的網頁保存在本地
    with open("douban_login_ver.html", "w") as f:
        print(r.text.encode(), file=f)

(最後還有會出現上次的字符串編碼問題,現在還是不知道原因,求指教ヾ(@^▽^@)ノ )

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