Win7 selenium 自动化chrome

Python3.8.10
selenium可以pip安装

chrome 109最后一个win7 版本,chromedriver 同样需要注意版本(存放位置后使用Service设置路径 )

编写时候注意:

find_elements()返回对象列表,find_element()返回对象!

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

service = Service(r"c:\chromedriver.exe")
driver = webdriver.Chrome(service=service)
driver.get("http://baidu.com/#/login")


#CLASS 选择器
driver.find_element(By.CLASS_NAME,"el-icon-arrow-up").click()
swap_c_s=driver.find_elements(By.CLASS_NAME, "el-select-dropdown__item")
time.sleep(3)
swap_c_s[7].click()
swap_c_v=driver.find_elements(By.CLASS_NAME,"el-input__inner")


#设置信息使用send_keys("")
swap_c_v[1].send_keys("admin")
swap_c_v[2].send_keys("admin")
driver.find_element(By.CLASS_NAME,"el-button--primary").click()

#Xpath选择器
driver.find_element(By.XPATH,'//span[contains(text(),"办理系统")]').click()
time.sleep(3)

打开页面必须 time.sleep 等待页面加载【JS动态页面必须注意AJAX回传也需要等待加载】

swap_tr_ones=driver.find_elements(By.XPATH,'(//table[contains(@class,"el-table__body")])[1]//tr')
for i in swap_tr_ones:
    tid=i.find_element(By.XPATH,'.//td[4]').text
    end=i.find_element(By.XPATH,'.//td[8]').text

#选择页面打开后 可以text 获取信息

打开新页面,需要使用driver.switch_to.window(driver.window_handles[1])
切换到之前的需要driver.switch_to.window(driver.window_handles[0]),上面二者后需要重新使用选择器抓取 ,关闭页面必须使用driver.close()

swap_click_ones=driver.find_elements(By.XPATH,'//table[contains(@class,"el-table__body")]//tr/td[4][not(contains(@class,"hidden"))]')
vx=[]
for i in swap_click_ones:
    i.click()
    time.sleep(3)
    driver.switch_to.window(driver.window_handles[1])
    driver.find_element(By.XPATH,'//span[contains(text(),"查看")]').click()
    #切换到新页面  老的页面 driver.switch_to.window(driver.window_handles[0])
    tid=driver.find_element(By.XPATH,'//label[contains(text(),"abc:")]/following-sibling::div/div').text
    phone=driver.find_element(By.XPATH,'//label[contains(text(),"电话")]/following-sibling::div').text
    info=driver.find_element(By.XPATH,'//label[contains(text(),"内容")]/following-sibling::div').text

    one={
        'tid':tid,
        'phone':phone,
        'info':info,
    }
    vx.append(one)
    driver.close()
    driver.switch_to.window(driver.window_handles[0])

图片保存图片

driver.save_screenshot("full_page.png")

元素保存图片

# 定位图片元素
img = driver.find_element(By.XPATH, "//img")
# 全屏截图临时文件
driver.save_screenshot("tmp.png")
full_img = Image.open("tmp.png")

# 获取元素位置尺寸
x = img.location['x']
y = img.location['y']
w = img.size['width']
h = img.size['height']

# 裁剪并保存
crop = full_img.crop((x, y, x + w, y + h))
crop.save("target_img.png")# 定位图片元素
img = driver.find_element(By.XPATH, "//img")
# 全屏截图临时文件
driver.save_screenshot("tmp.png")
full_img = Image.open("tmp.png")

# 获取元素位置尺寸
x = img.location['x']
y = img.location['y']
w = img.size['width']
h = img.size['height']

# 裁剪并保存
crop = full_img.crop((x, y, x + w, y + h))
crop.save("target_img.png")

Download 下载内容

https://www.python.org/downloads/release/python-3810

https://edgedl.me.gvt1.com/edgedl/release2/chrome/acihtkcueyye3ymoj2afvv7ulzxa_109.0.5414.120/109.0.5414.120_chrome_installer.exe

https://registry.npmmirror.com/binary.html?path=chromedriver/109.0.5414.74

发表在 None | 留下评论

基础回测框架

核心先创建需要的值,然后使用比较,然后创建新的df,将符合条件的df需要的值添加到新的df中,再合并新的df

import pymysql
from pymysql.err import OperationalError, ProgrammingError
import pandas as pd
import time
import numpy as np

# 数据库配置
config = {
    "host": "localhost",
    "port": 3306,
    "user": "root",
    "password": "a123456",
    "database": "gupiao",
    "charset": "utf8mb4"
}

conn = pymysql.connect(**config)
cursor = conn.cursor()

def get_all_data(mcode):
    start = time.time()
    sql = "SELECT * FROM cmf_quant6 WHERE mcode = %s AND date>'2025-10-01' ORDER BY date ASC"
    df = pd.read_sql(sql, conn, params=(mcode,))
    # 清理异常值(必须保留)
    df = df.replace([float('inf'), -float('inf')], 0)
    df = df.fillna(0)
    return df

def lb(df):
    df['lb']=100*(df['high']-df['preclose'])/df['preclose']
    mask=(df['lb']>df['pctChg'])&(df['lb'] >9.9)&(df['pctChg']>5.5)
    result_df=df[mask].copy()
    result_df['open_1']=df['open'].shift(-1)[mask]
    result_df['close_1']=df['close'].shift(-1)[mask]
    result_df['high_1']=df['high'].shift(-1)[mask]
    result_df['low_1']=df['low'].shift(-1)[mask]
    result_df['turn_1']=df['turn'].shift(-1)[mask]
    result_df['pctChg_1']=df['pctChg'].shift(-1)[mask]

    result_df['open_2']=df['open'].shift(-2)[mask]
    result_df['close_2']=df['close'].shift(-2)[mask]
    result_df['high_2']=df['high'].shift(-2)[mask]
    result_df['low_2']=df['low'].shift(-2)[mask]
    result_df['turn_2']=df['turn'].shift(-2)[mask]
    result_df['pctChg_2']=df['pctChg'].shift(-2)[mask]

    result_df['open_3']=df['open'].shift(-3)[mask]
    result_df['close_3']=df['close'].shift(-3)[mask]
    result_df['high_3']=df['high'].shift(-3)[mask]
    result_df['low_3']=df['low'].shift(-3)[mask]
    result_df['turn_3']=df['turn'].shift(-3)[mask]
    result_df['pctChg_3']=df['pctChg'].shift(-3)[mask]

    result_df['OO21']=(result_df['open_2']-result_df['open_1'])/result_df['open_1']
    result_df['OO31']=(result_df['open_3']-result_df['open_1'])/result_df['open_1']

    result_df['OC21']=(result_df['close_2']-result_df['open_1'])/result_df['open_1']
    result_df['OC31']=(result_df['close_3']-result_df['open_1'])/result_df['open_1']

    result_df.dropna(inplace=True)
    return result_df
    
    
results = []
df = pd.read_csv('/home/may/gupiao/all.csv', dtype={'code': str})
i = 0
for index, row in df.iterrows():
    pre_3=row['code'][0:2]
    if pre_3=="30" or pre_3=="68":
        continue
    print(i)
    i=i+1
    df = get_all_data(row['code'])
    processed_df=lb(df)
    results.append(processed_df)
    # if i>100:
    #     break

final_df = pd.concat(results, ignore_index=True)
final_df.to_csv("lanban2.csv", index=False, encoding="utf-8-sig")

# 关闭连接
cursor.close()
conn.close()
发表在 None | 留下评论

Script 复习 抓取内容打印

打印tabale 中的tr td其中的内容

    const rows = document.querySelectorAll('table tbody tr');
    
    // 跳过第一行(索引0),从索引1开始
    for (let i = 1; i < rows.length; i++) {
        const row = rows[i];
        const cells = row.querySelectorAll('td');
        
        console.log(`第 ${i + 1} 行(实际第 ${i} 行):`);
        console.log(`  第1列:`, cells[0]?.textContent.trim());
        console.log(`  第2列:`, cells[1]?.textContent.trim());
        console.log(`  第4列:`, cells[3]?.textContent.trim());
        console.log('---');
    }

备用 上面的好用,下面的备用

const rows = document.querySelectorAll('table tbody tr');
    
    console.log(`共找到 ${rows.length} 行`);
    
    rows.forEach((row, index) => {
        const cells = row.querySelectorAll('td');
        
        // 获取指定列(注意索引从0开始)
        const col1 = cells[0]?.textContent.trim() || '';  // 第1个td
        const col2 = cells[1]?.textContent.trim() || '';  // 第2个td
        const col4 = cells[3]?.textContent.trim() || '';  // 第4个td
        
        console.log(`第 ${index + 1} 行:`);
        console.log(`  第1列:`, col1);
        console.log(`  第2列:`, col2);
        console.log(`  第4列:`, col4);
    });

发表在 None | 留下评论

SCRIPT 专精提升:AJAX /# hash 动态网站/延时

发起AJAX请求

AJAX使用Script 内置,下面是DEMO GET与POST

注意:

// @grant GM_xmlhttpRequest
// @connect httpbin.org

上面两个 必须拥有 ,可以将GM_xmlhttpRequest封装成函数调用。

// ==UserScript==
// @name         AJAX DEMO GET-POST
// @namespace    https://docs.scriptcat.org/
// @version      0.1.0
// @description  try to take over the world!
// @author       You
// @match        https://el.psy.congroo.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=el.psy.congroo.com
// @grant        GM_xmlhttpRequest
// @connect      httpbin.org

// ==/UserScript==

(function() {
    'use strict';

// GET DEMO
    GM_xmlhttpRequest({
        method: "GET",
        url: "https://httpbin.org/get?name=Saya&to=lora",
        onload: function(response) {
            console.log('请求成功,状态码:', response.status);
            console.log('响应内容:', response.responseText);
        },
        onerror: function(error) {
            console.error('请求失败:', error);
        }
    });

// POST表单 传入 数据 JSON返回 DEMO
    const searchData = new URLSearchParams({
        keyword: "JavaScript教程",
        page: "1",
        sort: "latest",
        category: "编程"
    });

    GM_xmlhttpRequest({
        method: "POST",
        url: "https://httpbin.org/post",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded"
        },
        data: searchData.toString(),
        responseType: 'json',  // ✅ 加上这一行
        onload: function(res) {
            const results = res.response;
            // results 为队像直接处理
            console.log('搜索结果:json字符串', res.responseText);
            console.log('搜索结果:json对象', res.response);
        }
    });



    // Your code here...
})();

动态网站。# 访问 不刷新网页

hash事件监听【需要在监听函数创建后执行】
window.addEventListener(‘hashchange’, pageChanged);
自动调用函数pageChanged

关键变量参数,获取当前网页#后面的数据


    function pageChanged() {
        const hash = window.location.hash;
        console.log('当前页面:', hash || '首页');
        
        // 根据不同 hash 做不同事
        if (hash === '#/list') {
            console.log('📋 列表页,抓取数据...');
            // 你的抓取代码
        } else if (hash === '#/detail') {
            console.log('📄 详情页,抓取数据...');
            // 你的抓取代码
        }
    }



    // 首次加载执行
    pageChanged();

加上延时 动态网站必备

# 还是之前的change函数
// ============ 延迟包装 ============
let timer = null;

function pageChangedWithDelay(delay = 400) {
clearTimeout(timer);
timer = setTimeout(() => {
pageChanged();
}, delay);
}

// ============ 监听 ============
// ✅ hash 变化时自动调用
window.addEventListener('hashchange', pageChangedWithDelay);
发表在 None | 留下评论

日内T 经验

可以使用1分钟 或者5分钟线

买入点MA5 上穿MA10 必须上升趋势下,前提MA5 MA10 都是上升趋势下,在MA5 MA10下降去情况下慢慢MA5 穿MA10 不要买入,趋势反转处 附近K线 没有上影线。

卖出点MA5下穿MA10 可以在MA5 下穿MA10 前卖出 只要有足够利润,MA5下穿MA10时候已经是利润非最大话,可以在K线见顶 即多根 上影子线时候下手。

发表在 None | 留下评论