Ver código fonte

删除 'spiders/ybm/config.py'

wangkun 1 mês atrás
pai
commit
8975d200ec
1 arquivos alterados com 0 adições e 417 exclusões
  1. 0 417
      spiders/ybm/config.py

+ 0 - 417
spiders/ybm/config.py

@@ -1,417 +0,0 @@
-# config.py - 药帮忙采集配置
-from datetime import datetime
-
-from dotenv import load_dotenv
-import os
-import oss2
-from PIL import Image
-from commons.Logger import logger
-from conn_mysql import MySQLPoolOnline
-
-
-# 步骤:加载 .env 文件(如需)
-# load_dotenv() 默认读取当前目录下的 .env;如在其他路径可手动指定
-# load_dotenv()
-
-# MySQL:与 conn_mysql.MySQLPoolOnline 一致(默认 drug_retrieve 线上库)。
-# 覆盖方式:环境变量 MYSQL_DRUG_HOST / MYSQL_DRUG_PORT / MYSQL_DRUG_USER /
-# MYSQL_DRUG_PASSWORD / MYSQL_DRUG_DB
-mysql_pool = MySQLPoolOnline()
-
-# 模糊匹配 URL
-def fuzzy_match_product_url_in_db_mysql(product_url):
-    # 先做非空校验
-    if not product_url:
-        logger.warning("鈿狅笍 寰呭尮閰嶇殑 product_url 涓虹┖锛岃烦杩囨暟鎹烘煡")
-        return None
-
-    # 如有需要可转义 % / _,避免 LIKE 通配符影响
-    # escaped_product_url = product_url.replace("%", "\%").replace("_", "\_")
-
-    try:
-        sql = "SELECT * FROM ybm_drug_middle WHERE product_link LIKE %s"
-        rows = mysql_pool.select_data(sql, (f"%{product_url}%",))
-        return rows[0] if rows else None
-    except Exception as e:
-        logger.error(f"MySQL 模糊匹配失败:{str(e)}")
-        return None
-
-
-
-
-# ==================== 从数据库提取任务 ====================
-def get_search_keywords_from_db(platform= 9, include_collect_config=False):
-    """读取待执行任务(status=3),返回单条任务字典;无任务返回空 dict。"""
-    sql = " SELECT * FROM retrieve_collect_task_allocate WHERE status = 1 AND platform = %s LIMIT 1 "
-
-    try:
-        rows = mysql_pool.select_data(sql, (platform,))
-        data = rows[0] if rows else {}
-        logger.debug(
-            "读取待执行任务完成 platform=%s task_id=%s",
-            platform,
-            data.get("id") if data else None,
-        )
-    except Exception as e:
-        logger.error(f"读取待执行任务失败,platform={platform},错误:{str(e)}")
-        data = {}
-    print(data)
-    return data
-
-
-def has_running_task(platform: int = 9) -> bool:
-    """检查指定 platform 在当天是否存在执行中任务(status=2)。"""
-    try:
-        day_start_ts = int(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp())
-        next_day_ts = day_start_ts + 24 * 60 * 60
-        sql = (
-            "SELECT 1 AS one FROM retrieve_collect_task_allocate "
-            "WHERE status = 2 AND platform = %s "
-            "AND update_time >= %s AND update_time < %s LIMIT 1"
-        )
-        rows = mysql_pool.select_data(sql, (platform, day_start_ts, next_day_ts))
-        return bool(rows)
-    except Exception as e:
-        logger.error(f"检查执行中任务失败,platform={platform},错误:{str(e)}")
-        return False
-
-
-if __name__ == '__main__':
-    get_search_keywords_from_db()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# ==================== 2. 反爬配置 ====================
-# 随机延迟范围(模拟真人操作)
-MIN_CLICK_DELAY = 1.5  # 点击最小延迟(秒)
-MAX_CLICK_DELAY = 3.5  # 点击最大延迟(秒)
-MIN_INPUT_DELAY = 0.1  # 输入最小延迟(秒)
-MAX_INPUT_DELAY = 0.3  # 输入最大延迟(秒)
-MIN_PAGE_DELAY = 2.0   # 页面最小等待(秒)
-MAX_PAGE_DELAY = 4.0   # 页面最大等待(秒)
-
-# 关键词之间的随机延迟(秒)
-MIN_KEYWORD_DELAY = 8.0
-MAX_KEYWORD_DELAY = 15.0
-
-# 滚动配置(目标 400px,含随机偏移)
-SCROLL_TARGET_DISTANCE = 400  # 目标滚动距离
-SCROLL_OFFSET_RANGE = 50       # 随机偏移范围
-SCROLL_STEP = 50               # 每次滚动步长
-SCROLL_INTERVAL = 0.05         # 步长间隔(秒)
-
-# ==================== 3. Cookie & 登录配置 ====================
-COOKIE_FILE_PATH = "ybm_cookies.json"  # Cookie 保存路径
-# Cookie 有效性验证页面
-LOGIN_VALIDATE_URL = "https://www.ybm100.com/new/"
-
-# 登录账号密码
-USERNAME = "18008650300"
-PASSWORD = "12345678"
-
-
-# USERNAME = "yjj112031"
-# PASSWORD = "123456"
-
-# 登录URL
-TARGET_LOGIN_URL = "https://www.ybm100.com/new/login"
-# "https://www.yyjzt.com/login?redirect=%2FgoodDetail%3FladderNum%26itemStoreId%3D124250306%26sourceProdetail%3D%252Fsearch%26is_store%3D0"
-
-# ==================== 4. 元素选择器配置 ====================
-# 基础选择器
-USERNAME_SELECTOR = "input[placeholder*=请输入账号]"
-PASSWORD_SELECTOR = "input[placeholder*=请输入密码]"
-LOGIN_BTN_SELECTOR = "button:has(span:text('登录'))"
-SEARCH_INPUT_SELECTOR = "input[placeholder*='药品名称/厂家名称']"
-SEARCH_INPUT_SELECTOR2 = "div.home-search-container-search-head"
-SEARCH_BTN_SELECTOR = "div.home-search-container-search-head-btn[data-scmd=\"text-搜索\"]"
-
-# 采集元素选择器可根据页面实际情况调整
-# 如页面结构变化,请优先更新以上选择器
-PRODUCT_ITEM_SELECTOR = "div.product-list-item"         # 商品项容器
-
-PRODUCT_TITLE_SELECTOR = "div.product-name"        # 商品标题
-PRODUCT_PRICE_SELECTOR = "div.main-price"       # 商品价格
-PRODUCT_STORE_SELECTOR = 'div.prduct-shop-name div.shop-name'  # 店铺名称
-PRODUCT_COMPANY_SELECTOR = "div.product-manufacturer"            # 公司名称
-PRODUCT_VALIDITY_SELECTOR = "div.product-period"     # 有效期
-# div.shop-info-container-left-info-name span
-# ==================== 5. 等待时间配置(秒) ====================
-ELEMENT_TIMEOUT = 10000
-LOGIN_AFTER_CLICK = 5000
-SEARCH_BTN_TIMEOUT = 5000
-COLLECT_DELAY = 3000
-DETAIL_LOAD_TIMEOUT = 5000  # 点击商品后等待详情加载时间
-
-# ==================== 6. 浏览器配置 ====================
-BROWSER_HEADLESS = False
-BROWSER_CHANNEL = "chrome"
-SLOW_MO_MIN = 50
-SLOW_MO_MAX = 100
-
-# ==================== 7. CSV 配置 ====================
-CSV_HEADERS = [
-    "商品标题", "商品采购价格", "商品折扣价格", "规格", "盒数",
-    "店铺名称", "公司名称",
-    "有效日期", "生产日期", "批准文号", "采集时间"
-]  # CSV 表头
-
-# 存放营业执照截图路径(如需)
-# cropped_screenshot_path =
-
-
-# 百度 OCR 配置
-request_url_config = "https://aip.baidubce.com/rest/2.0/ocr/v1/business_license"
-
-AppKey_config = "tRK2RhyItCSh6BzyT4CNVXQa"
-AppSecret_config = "TDgKiPo94i2mOM1sDqOuDnlcK1bG66jh"
-token_url_config = 'https://aip.baidubce.com/oauth/2.0/token'
-
-
-
-
-
-# ---------------------- OSS 配置 ----------------------
-OSS_ACCESS_KEY_ID = 'LTAI5tDwjfteBvivYN41r8sJ'
-OSS_ACCESS_KEY_SECRET = 'yowuOGi2nYYnrqGpO3qcz94C4brcPp'
-OSS_ENDPOINT = "oss-cn-shenzhen.aliyuncs.com"
-OSS_BUCKET_NAME = "zhijiayun-jiansuo"
-OSS_PREFIX = "scrape_data/"
-
-
-
-# 本地截图配置
-LOCAL_SCREENSHOT_DIR = "local_screenshots"  # 本地截图目录
-LOCAL_SCREENSHOT_NAME = None  # 自动生成文件名
-LOCAL_CROPPED_DIR = "./local_cropped_screenshots"  # 裁剪后目录
-
-
-# 图片压缩配置
-IMAGE_COMPRESS_ENABLE = True  # 是否启用压缩(True/False)
-IMAGE_COMPRESS_QUALITY = 30  # JPG 质量(1-95)
-IMAGE_COMPRESS_PNG_LEVEL = 9  # PNG 压缩级别(0-9)
-
-
-# ---------------------- 宸ュ叿鍑芥暟 ----------------------
-def init_local_screenshot_dir():
-    """初始化本地截图目录(不存在则创建)。"""
-    if not os.path.exists(LOCAL_SCREENSHOT_DIR):
-        os.makedirs(LOCAL_SCREENSHOT_DIR)
-        logger.info(f"本地截图目录已创建: {LOCAL_SCREENSHOT_DIR}")
-    else:
-        logger.debug(f"本地截图目录已存在: {LOCAL_SCREENSHOT_DIR}")
-
-
-
-def init_oss_bucket():
-    """初始化 OSS Bucket 对象。"""
-    try:
-        auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
-        bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)
-        bucket.get_bucket_info()
-        logger.info("OSS Bucket 初始化成功")
-        return bucket
-    except Exception as e:
-        logger.error(f"OSS Bucket 初始化失败: {str(e)}")
-        raise
-
-
-
-def upload_local_screenshot_to_oss(bucket, local_file_path, oss_file_path=None):
-    """将本地截图上传到 OSS,返回公网访问链接。"""
-    if not os.path.exists(local_file_path):
-        raise FileNotFoundError(f"本地截图文件不存在: {local_file_path}")
-
-    if not oss_file_path:
-        local_file_name = os.path.basename(local_file_path)
-        oss_file_path = f"screenshots/{local_file_name}"
-
-    try:
-        bucket.put_object_from_file(oss_file_path, local_file_path)
-        oss_file_url = f"https://{OSS_BUCKET_NAME}.{OSS_ENDPOINT}/{oss_file_path}"
-        logger.info(f"截图上传 OSS 成功: {oss_file_url}")
-        return oss_file_url
-    except Exception as e:
-        logger.error(f"截图上传 OSS 失败: {str(e)}")
-        raise
-
-# ---------------------- 图片裁剪与压缩 ----------------------
-def crop_local_screenshot(local_file_path, cropped_file_path=None, crop_region=None):
-    """裁剪本地截图并保存,成功后删除原图,返回裁剪后文件路径。"""
-    if not os.path.exists(local_file_path):
-        raise FileNotFoundError(f"原始截图文件不存在: {local_file_path}")
-
-    os.makedirs(LOCAL_CROPPED_DIR, exist_ok=True)
-
-    if not cropped_file_path:
-        file_name = os.path.basename(local_file_path)
-        file_name_no_ext, file_ext = os.path.splitext(file_name)
-        cropped_file_name = f"{file_name_no_ext}_cropped{file_ext}"
-        cropped_file_path = os.path.join(LOCAL_CROPPED_DIR, cropped_file_name)
-
-    with Image.open(local_file_path) as img:
-        img_width, img_height = img.size
-        logger.debug(f"原图尺寸: width={img_width}, height={img_height}")
-
-        if not crop_region:
-            left = 0
-            upper = 0
-            right = int(img_width)
-            lower = int(img_height * 0.3)
-            crop_region = (left, upper, right, lower)
-            logger.debug(f"未指定裁剪区域,使用默认区域: {crop_region}")
-
-        c_left, c_upper, c_right, c_lower = crop_region
-        if c_right > img_width or c_lower > img_height or c_left < 0 or c_upper < 0:
-            raise ValueError(
-                f"裁剪区域超出图片范围,图片尺寸=({img_width}, {img_height}),裁剪区域={crop_region}"
-            )
-
-        cropped_img = img.crop(crop_region)
-
-        file_ext = os.path.splitext(cropped_file_path)[1].lower()
-        try:
-            if IMAGE_COMPRESS_ENABLE:
-                if file_ext in ['.jpg', '.jpeg']:
-                    cropped_img.save(
-                        cropped_file_path,
-                        format='JPEG',
-                        quality=IMAGE_COMPRESS_QUALITY,
-                        optimize=True,
-                        progressive=True,
-                    )
-                else:
-                    cropped_img.save(cropped_file_path)
-                logger.info(f"裁剪图片已保存(压缩开启): {cropped_file_path}")
-            else:
-                cropped_img.save(cropped_file_path, format='JPEG')
-                logger.info(f"裁剪图片已保存(压缩关闭): {cropped_file_path}")
-        except Exception as e:
-            cropped_img.save(cropped_file_path, format='JPEG')
-            logger.warning(f"图片压缩失败,已按普通 JPEG 保存: {str(e)}")
-
-    try:
-        if os.path.exists(cropped_file_path):
-            os.remove(local_file_path)
-            logger.debug(f"已删除原始截图: {local_file_path}")
-        else:
-            logger.warning(f"裁剪文件不存在,跳过删除原图: {cropped_file_path}")
-    except OSError as e:
-        logger.warning(f"删除原始截图失败: {str(e)}")
-
-    return cropped_file_path
-
-
-def screenshot_target_page_to_local_then_oss(target_page, local_file_path=None, oss_file_path=None, full_page=True, crop_region=None):
-    """页面截图到本地后裁剪,再上传 OSS,返回(裁剪路径, OSS链接)。"""
-    os.makedirs(LOCAL_SCREENSHOT_DIR, exist_ok=True)
-
-    if not local_file_path:
-        current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
-        local_file_name = f"{current_time}_target_page.jpg"
-        local_file_path = os.path.join(LOCAL_SCREENSHOT_DIR, local_file_name)
-
-    logger.info(f"开始页面截图: {local_file_path}")
-    target_page.screenshot(
-        path=local_file_path,
-        full_page=full_page,
-        omit_background=False,
-        timeout=10000,
-    )
-    logger.debug("页面截图完成")
-
-    cropped_file_path = crop_local_screenshot(
-        local_file_path=local_file_path,
-        crop_region=crop_region,
-    )
-
-    bucket = init_oss_bucket()
-    oss_file_url = upload_local_screenshot_to_oss(bucket, cropped_file_path, oss_file_path)
-
-    return cropped_file_path, oss_file_url