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)

(最后还有会出现上次的字符串编码问题,现在还是不知道原因,求指教ヾ(@^▽^@)ノ )

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