使用selenium获得的cookies测试没有问题,但是获得的heards头不可以使用,经过测试比较 需要添加或者修改几项重点的heards为
{'Cipher-Text': '1704885072633_1704970047346_SlMkwPX0ZnotTaSrpOEx50xhLlPT5iMH867nxTtYuapcdPhsh2d2ooVE2F+RSm+yhIFdYwl9hYefGsuc5F9ml4mT712T3ihceocXBBzUWrwBKjSeIwOfzX1Y0nWI4lKgOeBjDz0cTMGYzs4aqGWUtTV6US8dNyW2jonhj5L/Ju+fmDbGgb7TUMGTQCZULOMktSNYXJxKaVMFCTX2XbSz0Hpmk00NwTeaKhdJSq4nbAxsitU+34sQXhNxZLkmGWVmW1Lb+uDK9MV0SX7o4bD/J0t2kGrQCP0ynKXTdfKyd/KUTXgJSlMNAXS5wyHbLTht81IJbp8/bUNLCgb+dJfxIOrbUCzgWuVRlPk4UWPDECfYXfLyqvtmB5b97AjOuYTo',
'Referer': 'https://index.baidu.com/v2/main/index.html',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin'}
获得新的heards后直接用代码
headers['Sec-Fetch-Mode'] = en_heard['Sec-Fetch-Mode']
headers['Sec-Fetch-Site'] = en_heard['Sec-Fetch-Site']
headers['Sec-Fetch-Dest'] = en_heard['Sec-Fetch-Dest']
headers['Sec-Fetch-Dest'] = en_heard['Sec-Fetch-Dest']
headers.update({'Referer':en_heard['Referer'] , 'Cipher-Text':en_heard['Cipher-Text'] })
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, “myElement”))
)
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, “button.myButton”))
)
就用selenium登录后调用方法获取就行
driver.get_cookies()
然后切分cookies使得可以直接使用
cookies = {cookie['name']: cookie['value'] for cookie in driver.get_cookies()}
这个部分正常的selenium是获得不了的,需要用到另一个库:seleniumwire
通过这个库的方法可以获得浏览器的heards,再添加一些关键词,就可以实现获得可用的heards
for request in driver.requests:
print('请求headers:')
print(request.headers)
headers = request.headers
headers = dict(headers)
break
这样就得到了可以直接使用的headrs
def get_driver():
chrome_path = "./114.0.5735.199_chrome_installer/Chrome-bin/chrome.exe"
# 无更新组件版本的谷歌浏览器
# 指定驱动路径
driver_path = "./chromedriver114.exe"
# 设置Chrome选项
chrome_options = Options()
chrome_options.binary_location = chrome_path
# chrome_options.add_argument("--headless") # 添加无界面功能参数
# 设置Chrome驱动服务
service = Service(driver_path)
# 启动带有自定义选项和服务的Chrome浏览器
driver = webdriver.Chrome(service=service, options=chrome_options)
return driver
同时有个重要的功能就是上面的
# chrome_options.add_argument("--headless") # 添加无界面功能参数
无界面也就是常说的无头模式的浏览器,这样的浏览器不会显示界面,比较适用于不需要和页面互动的任务或者想提升效率的任务
在selenium中,很多报错是因为元素点击不了,有很多原因,有可能是被挡住了,有可能是有一部分被挡住了,有可能是还没有加载出来,有一个解决百分之80的办法就是使用js,没必要使用selenium自带的移动模拟鼠标和点击,直接使用js,点击元素最为方便
element = driver.find_element(By.XPATH, "//p[@id='TANGRAM__PSP_4__footerQrcodeBtn']")
driver.execute_script("arguments[0].click();", element)
通用还有好处是,js点击不会报错,常用的场景是,有一个广告,并不是每次都会出现,如果你要是点击他但是没有还会报错,用js就可以解决这个问题,js执行之后不论成功不成功,并不会报错,比较安全
js还有个常用的功能是滚动到目标元素的位置,通过这个方法可以解决那些因为元素不在界面所以无法点击的问题,常见的情况是:在一个界面中有多选框,点开之后有一部分在下面再遮挡
import winsound
duration = 500 # millisecond持续时间
freq = 500 # Hz频率
# winsound.Beep(freq, duration)
for i in range(5):
duration = 100 # millisecond持续时间
freq = 500 # Hz频率
winsound.Beep(freq, duration)
selenium有时候有的元素不确定什么时候才会加载好,个人觉得好使的方法有两种,一种是等待这个元素直到他可以被点击为止:
from selenium 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
# 设置等待时间直到一个元素可以被点击
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, 'myElement'))
)
第二种是,等待这个元素直到这个元素加载完成:
from selenium 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
# 设置等待时间直到页面加载完毕
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, 'myElement'))
)
注意,要导入的库WebDriverWait和EC
需要为创建驱动这个方法创建一个工具类:
from selenium import webdriver
class WebDriverManager:
_driver = None
@classmethod
def get_driver(cls):
if not cls._driver:
cls._driver = webdriver.Chrome() # 这里可以根据需要选择合适的浏览器
return cls._driver
@classmethod
def close_driver(cls):
if cls._driver:
cls._driver.quit()
cls._driver = None
这两个方法在工具类中可以做到创建驱动和关闭驱动,在主flask文件导入这个模块的WebDriverManager之后调用get或close方法就可以使用同一个驱动了,亲测可用
导入模块
from driverget import WebDriverManager
#在需要创建驱动的地方这样创建
driver = WebDriverManager.get_driver()
可以更方便的定位元素,更加人性化的设计
方法1
# 不变的参数
constant_value = "Constant"
# 可迭代参数
iterable1 = [1, 2, 3]
iterable2 = ['a', 'b', 'c']
# 使用 map 调用函数
result = map(my_function, [constant_value]*len(iterable1), iterable1, iterable2)
可以给不边的对象用列表然后长度和迭代的对齐来解决,即:[不变的变量]*len(变的对象的长度)
1
for i in range(1, 6):
globals()[f"fu{i}"] = i
# 验证创建的变量
print(fu1) # 输出:1
print(fu2) # 输出:2
print(fu3) # 输出:3
print(fu4) # 输出:4
print(fu5) # 输出:5
2
# 创建一个空字典以存储动态变量
dynamic_variables = {}
# 使用拼接的方法创建变量
for i in range(1, 6):
dynamic_variables[f"fu{i}"] = i
# 验证创建的变量
print(dynamic_variables['fu1']) # 输出:1
print(dynamic_variables['fu2']) # 输出:2
print(dynamic_variables['fu3']) # 输出:3
print(dynamic_variables['fu4']) # 输出:4
print(dynamic_variables['fu5']) # 输出:5
3
class DynamicVariables:
def __init__(self):
pass
# 创建类的实例
dynamic_obj = DynamicVariables()
# 使用 setattr 方法动态创建属性
for i in range(1, 6):
setattr(dynamic_obj, f"fu{i}", i)
# 验证创建的属性
print(dynamic_obj.fu1) # 输出:1
print(dynamic_obj.fu2) # 输出:2
print(dynamic_obj.fu3) # 输出:3
print(dynamic_obj.fu4) # 输出:4
print(dynamic_obj.fu5) # 输出:5
y轴自动划分精度
自动设置 y 轴的刻度
ax.locator_params(axis='y', nbins=10)
在中间绘制一条虚线,用来整平均值
# 计算平均值
mean_value = df['value'].mean()
# 绘制柱状图
ax = df.plot(kind='bar', x='category', y='value', rot=45)
# 添加表示平均值的虚线
ax.axhline(y=mean_value, color='r', linestyle='--', linewidth=2) # 绘制红色虚线,线宽为2
设置 y 轴的取值范围和刻度
ax.set_ylim(0, 100) # 设置 y 轴的取值范围
ax.set_yticks([0, 25, 50, 75, 100]) # 设置 y 轴的刻度
ALTER TABLE your_table_name
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;