感谢您提供代码。这段代码有一些问题,例如:
Dm()
类没有定义url
变量,因此在登录方法中会出现错误。在登录方法中的 try-except 块中缺少一个 try 语句。
load_cookies
方法接收了两个参数:self
和cookie_file
,但在其他地方调用时只传递了一个参数。应该将self.cookie_file
用作默认值。在 parse 方法中,缺少必要的请求 url。
缩进不一致可能导致语法错误或意外行为。
根据上述问题,下面是修改后的代码:
# -*- coding: utf-8 -*-
"""
Created on 2023-05-05 12:37:32
---------
@summary:
---------
@author:
"""
import time
import pickle
from selenium import webdriver
import pytesseract
from PIL import Image
from lxml import etree
import feapder
from feapder.utils.webdriver import WebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class Dm(feapder.AirSpider):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.cookie_file = "dm_cookies.txt" # 保存 cookie 的文件名
def start_requests(self):
yield feapder.Request(
"https://m.damai.cn/damai/minilogin/index.html?returnUrl=https%3A%2F%2Fm.damai.cn%2Fapp%2Fdmfe%2Fh5-ultron-buy%2Findex.html%3FbuyParam%3D720545258599_1_5016701340287%26buyNow%3Dtrue%26exParams%3D%25257B%252522channel%252522%25253A%252522damai_app%252522%25252C%252522damai%252522%25253A%2525221%252522%25252C%252522umpChannel%252522%25253A%252522100031004%
22 % 25 22subChannel % 25 22 : % 25 22damai % 2540damaih5_h5 % 25 22atomSplit % 25
22:1 % 257D & spm = undefined & sqm = dianying.h5.unknown.value & spm=a2o71.project.0.0",
callback=self.login,
dont_filter=True,
render=True,
request_type="login"
)
# 使用保存的 Cookie 自动登录
def login(self, request, response):
try:
# 定义请求 url
url = "https://m.damai.cn/app/dmfe/h5-ultron-buy/index.html?buyParam=720545258599_1_5016701340287&buyNow=true&exParams=%7B\"channel\":\"damai_app\",\"damai\":\"1\",\"umpChannel\":\"100031004\",\"subChannel\":\"damai@damaih5_h5\",\"atomSplit\":1\}&spm=undefined&sqm=dianying.h5.unknown.value"
# 从文件中读取 Cookie
cookies = self.load_cookies()
if cookies:
# 如果 Cookie 已存在,则直接使用 Cookie 发送请求
headers = {
"Cookie": "; ".join([f"{c['name']}={c['value']}" for c in cookies])
}
yield feapder.Request(url=url, headers=headers, render=True)
else:
# 如果 Cookie 不存在,则需要手动输入账号和密码登录并保存 Cookie
print("请在浏览器中手动输入账号和密码,并登录网站")
print("登录成功后,请勿退出登录或清除浏览器缓存,本程序会自动化获取验证码并登录")
# 输入验证码自动登录
browser = webdriver.Chrome()
browser.get(url)
# 等待用户手动输入用户名和密码后,自动跳转到首页
input("请在浏览器中完成登录操作,完成后按 Enter 键继续...")
# 保存 Cookie
cookies = browser.get_cookies()
with open(self.cookie_file, "wb") as f:
pickle.dump(cookies, f)
browser.quit()
# 使用保存的 Cookie 发送请求
headers = {
"Cookie": "; ".join([f"{c['name']}={c['value']}" for c in cookies])
}
yield feapder.Request(url=url, headers=headers, render=True)
except Exception as e:
print(f"登录失败:{str(e)}")
def load_cookies(self, cookie_file=None):
if not cookie_file:
cookie_file = self.cookie_file
# 从文件中读取 cookies
try:
with open(cookie_file, "rb") as f:
cookies = pickle.load(f)
# 将 cookies 转换为字典类型
cookies_dict = {}
for cookie in cookies:
cookies_dict[cookie['name']] = cookie['value']
return cookies_dict
except Exception as e:
print(f"无法读取 Cookie 文件:{str(e)}")
def parse(self, request, response):
start = time.time()
browser: WebDriver = response.browser
wait = WebDriverWait(browser, 10)
# 选城市
but = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="card-720545258599"]/div/div')))
but.click()
# 选场次
but_chengshi = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div/div[1]/div[3]/div')))
but_chengshi.click()
# 选多少钱的场次
but_1717 = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[6]/div[2]/div/div/div/div/div[3]/div[2]/div[6]/div[1]')))
but_1717.click()
# 确认选座
Click_OK = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[6]/div[2]/div/div/div/div/div[4]/div[2]/div[2]')))
Click_OK.click()
print(time.time() - start)
if __name__ == "__main__":
Dm().start()