使用pytesseract和Cookie登录古诗文网~(python爬虫)

发布于:2025-04-03 ⋅ 阅读:(39) ⋅ 点赞:(0)

以下的代码是一个使用Python实现的古诗文网(gushiwen.cn)自动化登录脚本,主要功能是通过模拟浏览器行为完成登录过程,并验证登录是否成功。

主要实现的功能

  1. 模拟浏览器登录功能

    • 使用urllib模拟浏览器发送HTTP请求

    • 自动处理ASP.NET的VIEWSTATE机制

  2. 验证码自动识别功能

    • 自动下载网页验证码图片

    • 使用Pillow库进行图像预处理(灰度化)

    • 调用pytesseract OCR引擎识别验证码文本

    • 对识别结果进行清洗和格式化

  3. 会话保持功能

    • 通过CookieJar自动管理会话Cookie

    • 使用HTTPCookieProcessor维持登录状态

    • 构建opener实现请求的连贯性

  4. 表单自动提交功能

    • 自动填充登录表单(邮箱、密码、验证码)

    • 自动提交POST请求完成登录

  5. 登录状态验证功能

    • 登录后自动访问测试页面

    • 通过检测"退出登录"文本验证登录状态

    • 输出当前会话的Cookie信息

  6. 页面内容获取功能

    • 使用lxml解析HTML页面

    • 提取页面标题等关键信息

  7. 异常处理功能

    • 对网络请求和验证码识别进行异常捕获

    • 提供错误信息输出

  8. 调试辅助功能

    • 打印关键步骤信息(验证码识别结果、登录状态等)

    • 输出当前获取的Cookie列表

  9. 自动化流程控制

    • 添加适当的延迟确保操作完成

    • 根据验证码识别结果决定是否继续登录流程

  10. 安全功能

    • 使用标准User-Agent模拟浏览器

    • 遵循标准HTTP协议流程

Cookie处理机制初始化:

cookiejar = CookieJar()
handler = HTTPCookieProcessor(cookiejar)
opener = build_opener(handler)
  • 创建CookieJar对象存储Cookie

  • 创建HTTPCookieProcessor处理Cookie

  • 构建opener用于发送请求并自动处理Cookie

获取登录页面和提取必要参数

req = Request(login_url, headers=header)
resp = opener.open(req)
html = etree.HTML(resp.read().decode('utf-8'))

viewstate = html.xpath("//input[@id='__VIEWSTATE']/@value")[0]
viewstategenerator = html.xpath("//input[@id='__VIEWSTATEGENERATOR']/@value")[0]
  • 发送GET请求获取登录页面

  • 解析HTML并提取ASP.NET特有的__VIEWSTATE__VIEWSTATEGENERATOR参数

  • 这些参数是ASP.NET表单必需的隐藏字段

验证码处理流程

code_url = "https://www.gushiwen.cn" + html.xpath("//img[@id='imgCode']/@src")[0]
req_code = Request(code_url, headers=header)
resp_code = opener.open(req_code)

image_data = resp_code.read()
image = Image.open(io.BytesIO(image_data))

# 图像预处理
image = image.convert('L')  # 灰度化

# 识别验证码
custom_config = r'--psm 7 --oem 3 -c tessedit_char_whitelist=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
textcode = pytesseract.image_to_string(image, config=custom_config)
textcode = textcode.strip().replace(' ', '')[:4]
  • 获取验证码图片URL并下载

  • 直接在内存中处理验证码图片

  • 对图片进行灰度化处理提高识别率

  • 使用pytesseract识别验证码,配置参数优化识别效果

  • 清理识别结果,只保留前4位字符

构造并提交登录请求

data = {
    '__VIEWSTATE': viewstate,
    '__VIEWSTATEGENERATOR': viewstategenerator,
    'email': '2833622025@qq.com',
    'pwd': 'ckn12138',
    'code': textcode,
    'denglu': '登录'
}

login_req = Request(
    login_url,
    data=urlencode(data).encode('utf-8'),
    headers=header
)
login_resp = opener.open(login_req)
  • 构造包含所有必需参数的POST数据

  • 使用urlencode编码数据

  • 发送登录请求

具体代码展示:

import requests
from lxml import etree
from PIL import Image
import pytesseract
from http.cookiejar import CookieJar
from urllib.request import HTTPCookieProcessor, build_opener, Request
from urllib.parse import urlencode
import io
import time

header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36"
}
login_url = "https://www.gushiwen.cn/user/login.aspx?from=http://www.gushiwen.cn/user/collect.aspx"
test_url = "https://www.gushiwen.cn/user/collect.aspx"

# 1. 创建Cookie处理器
cookiejar = CookieJar()
handler = HTTPCookieProcessor(cookiejar)
opener = build_opener(handler)

# 2. 获取登录页面和必要参数
req = Request(login_url, headers=header)
resp = opener.open(req)
html = etree.HTML(resp.read().decode('utf-8'))

viewstate = html.xpath("//input[@id='__VIEWSTATE']/@value")[0]
viewstategenerator = html.xpath("//input[@id='__VIEWSTATEGENERATOR']/@value")[0]

# 3. 下载验证码并用pytesseract识别
code_url = "https://www.gushiwen.cn" + html.xpath("//img[@id='imgCode']/@src")[0]
req_code = Request(code_url, headers=header)
resp_code = opener.open(req_code)

# 将验证码图片直接读入内存进行处理
image_data = resp_code.read()
image = Image.open(io.BytesIO(image_data))

# 图像预处理(根据实际验证码调整)
image = image.convert('L')  # 灰度化
# image = image.point(lambda x: 0 if x < 128 else 255, '1')  # 二值化

# 识别验证码
custom_config = r'--psm 7 --oem 3 -c tessedit_char_whitelist=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
textcode = pytesseract.image_to_string(image, config=custom_config)
textcode = textcode.strip().replace(' ', '')[:4]  # 清理结果并取前4位
print("pytesseract识别的验证码:", textcode)

# 4. 构造登录数据并提交
if len(textcode) == 4:
    data = {
        '__VIEWSTATE': viewstate,
        '__VIEWSTATEGENERATOR': viewstategenerator,
        'email': '2833622025@qq.com',  # 替换为你的邮箱
        'pwd': 'ckn12138',             # 替换为你的密码
        'code': textcode,
        'denglu': '登录'
    }

    # 使用urllib的方式提交登录请求
    login_req = Request(
        login_url,
        data=urlencode(data).encode('utf-8'),
        headers=header
    )
    login_resp = opener.open(login_req)
    login_html = login_resp.read().decode('utf-8')
    
    # 添加延迟,确保登录完成
    time.sleep(2)

    # 测试是否登录成功
    test_req = Request(test_url, headers=header)
    try:
        test_resp = opener.open(test_req)
        test_html = test_resp.read().decode('utf-8')

        if "退出登录" in test_html:
            print("登录成功!")
            # 打印当前保存的Cookie
            print("当前Cookie:", [cookie.name for cookie in cookiejar])
            
            # 获取登录后的页面内容示例
            print("获取收藏页面标题:")
            doc = etree.HTML(test_html)
            title = doc.xpath('//title/text()')[0]
            print(title)
        else:
            print("登录失败,请检查账号或验证码!")
    except Exception as e:
        print("访问测试页面出错:", str(e))
else:
    print("验证码识别失败")

运行结果:

一般是识别不出来的 偶尔会成功 最好是用超级鹰来识别

当然也有成功地时候 多试几次就好~