¿Cómo obtener información del artículo a través de la automatización de la interfaz de usuario?

Para estudio e investigación, analicé los artículos y videos de cierta cuenta, y traté de usar métodos automatizados para ver si podía obtener la información correspondiente.

Existen múltiples formas de obtener artículos de un determinado número:

El primero es buscar la cuenta a través del navegador Sogou (este método solo puede obtener un artículo por día, lo cual es básicamente inútil):

imagen

Si desea aprender a probar la automatización de la interfaz, aquí le recomiendo una serie de videos. Se puede decir que este video es el tutorial de prueba de automatización de la interfaz número uno en toda la red en la estación B. Al mismo tiempo, el número de en línea usuarios ha llegado a 1.000, y hay notas para coleccionar y usar Intercambios técnicos de varios maestros: 798478386    

[Actualizado] La colección más detallada de tutoriales prácticos para pruebas automatizadas de interfaces de Python impartidas por la estación B (la última versión de combate real)_哔哩哔哩_bilibili [Actualizado] La colección más detallada de tutoriales prácticos para pruebas automatizadas de Python interfaces impartidas por la estación B (combate real) La última versión) tiene un total de 200 videos, que incluyen: 1. [Automatización de interfaz] La situación actual del mercado de pruebas de software y los estándares de capacidad de los probadores. , 2. [Automatización de interfaz] Totalmente capacitado en la biblioteca de solicitudes y la lógica de llamada de método subyacente, 3. [Automatización de interfaz] combate de automatización de interfaz y la aplicación de expresiones regulares y extractores JsonPath, etc. Para videos más emocionantes, preste atención a la cuenta UP. https://www.bilibili.com/video/BV17p4y1B77x/?spm_id_from=333.337&vd_source=488d25e59e6c5b111f7a1a1a16ecbe9a 

El segundo método requiere que usted mismo registre una cuenta de suscripción, y existen restricciones en la cuenta de registro:

1. Un correo electrónico solo puede solicitar una cuenta;

2. El mismo número de teléfono móvil puede vincularse a 5 cuentas;

3. El número máximo de cuentas personales registradas con un mismo DNI es 1;

4. El número máximo de cuentas registradas para la misma empresa, hogar industrial y comercial individual y otros materiales organizativos es 2;

5. El mismo tipo de gobierno y medio puede registrar y autenticar 50 cuentas;

6. El número máximo de cuentas registradas por una misma entidad en el extranjero es 1.

Significa que una persona solo puede registrar un número y puede solicitar un medio o un gobierno con números 50. Para investigación y estudio, uno es suficiente.

Sin mencionar el proceso de registro, después de registrarse e iniciar sesión, haga clic en "cuadro de borrador" ---> 'escribir nueva imagen y texto' ---> haga clic en el 'hipervínculo' en la parte superior --> haga clic en 'seleccionar otra cuenta' en la cuenta --> Ingrese el nombre de la cuenta que necesita obtener artículos , haga clic en Consulta, puede ver en este momento, se obtendrán todos los artículos de esta cuenta:

imagen

Por ejemplo, si consultamos "CCTV", los artículos se mostrarán en orden inverso según la fecha de publicación, este es el dato que queremos obtener. Nuestra operación automatizada se simulará en este lugar, y el resto es solo para analizar la interfaz:

A través del análisis de solicitudes, la solicitud para obtener artículos es:

https://mp.weixin.qq.com/cgi-bin/appmsg?action=list_ex&begin=35&count=5&fakeid=MTI0MDU3NDYwMQ==&type=9&query=&token=441171486&lang=zh_CN&f=json&ajax=1

imagen

Los datos devueltos por la interfaz son muy completos y básicamente todos los datos que desea están disponibles.

Que tenemos que hacer:

1. Simule automáticamente la operación del usuario a la acción actual, luego obtenga la conexión de la solicitud y analice los datos de la solicitud

2. Para llamar directamente a esta interfaz para obtener datos, entonces es necesario construir los parámetros de solicitud de esta interfaz, como identificación de cuenta, cookie, etc., mantenimiento de inicio de sesión, etc.

Al comparar los dos métodos, ambos tienen ventajas correspondientes. Para la automatización, solo necesita ingresar el nombre de la cuenta después de iniciar sesión. Si llama a la interfaz, las diferentes cuentas deben mantener la identificación correspondiente por adelantado, y es más fácil bloquearlas si usted llama a la interfaz directamente.

Las reglas de ban actualmente investigadas son: cada cuenta puede llamar a la interfaz 60 veces, y será baneado por 1 hora cuando llegue a 60. Es inútil cambiar la IP, y puede continuar después de 1 hora. veces, el tiempo de prohibición cambiará. largo, hasta 24 horas.

Algunas personas dicen, sin llamar a la interfaz, ¿cómo obtener estas solicitudes después de la automatización? Hay dos maneras:

  1. La ventaja de instalar mitmproxy en comparación con Charles y fiddler es que se puede simular mediante línea de comando o secuencia de comandos.

Mitmproxy no solo puede capturar paquetes como Charles, sino que también puede realizar un desarrollo secundario en los datos solicitados e ingresar un alto grado de personalización secundaria.

Primero puede consultar los documentos relevantes en el sitio web oficial

Sitio web oficial de mitmproxy: https://www.mitmproxy.org/
mitmproxy es muy poderoso, pero no lo necesitamos aquí.

1.alambre de selenio 

Selenium Wire amplía los enlaces Python de Selenium para brindarle acceso a las solicitudes subyacentes realizadas por el navegador. Usted escribe código de la misma manera que escribe Selenium, pero obtiene API adicionales para inspeccionar solicitudes y respuestas y cambiarlas dinámicamente. Sitio web oficial de mitmproxy:

https://github.com/wkeeling/selenium-alambre

  • Python puro, API fácil de usar

  • Solicitudes HTTP y HTTPS capturadas

  • Interceptar solicitudes y respuestas

  • Modifique encabezados, parámetros, contenido del cuerpo sobre la marcha

  • Capturar mensajes de websocket

  • Formato HAR compatible

  • Soporte de servidor proxy

Seleniumwire es suficiente para nosotros. 

Después de saber cómo hacerlo, resolvamos lo que necesitamos preparar:

1. Instalación del entorno

(1) entorno de python (omitido)

(2) descarga del controlador Chromedriver:

http://chromedriver.storage.googleapis.com/index.html

(3) entorno mysql (omitido)

2. Diseño de base de datos

(1) weichat_news: tabla principal de noticias


CREATE TABLE `weichat_news` (
  `id` int NOT NULL AUTO_INCREMENT,
  `news_title` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章名称',
  `news_cover` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章封面图',
  `news_digest` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章简要',
  `news_content_link` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章内容连接',
  `account_id` int NOT NULL COMMENT '微信账号id',
  `weichat_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '微信账号名称',
  `news_create_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文章创建时间',
  `news_update_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文章更新时间',
  `update_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新时间',
  `insert_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '文章插入时间',
  `is_video` int NOT NULL DEFAULT '0' COMMENT '是否执行video扫描',
  `have_video` int NOT NULL DEFAULT '0' COMMENT '是否含有视频',
  `is_content` int NOT NULL DEFAULT '0' COMMENT '是否获取内容',
  `is_push` int DEFAULT '0',
  `is_delete` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `title` (`news_title`) USING BTREE,
  KEY `link` (`news_content_link`) USING BTREE,
  KEY `idx_account_id` (`account_id`) USING BTREE,
  KEY `idx_1` (`have_video`,`is_delete`,`is_push`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='文章';

(2) weichat_account: la tabla de cuentas que debe obtenerse


CREATE TABLE `weichat_account` (
  `id` int NOT NULL AUTO_INCREMENT,
  `account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号名称',
  `collection_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  `is_delete` int DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='账号';

(3) run_account: tabla de ejecución de cuentas


CREATE TABLE `run_account` (
  `id` int NOT NULL AUTO_INCREMENT,
  `account_id` int NOT NULL COMMENT '账号id',
  `account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号名称',
  `patch` int DEFAULT NULL,
  `run_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '执行时间',
  `is_delete` int DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='执行情况';

(4) news_video: tabla de videos


CREATE TABLE `news_video` (
  `id` int NOT NULL AUTO_INCREMENT,
  `news_id` int NOT NULL COMMENT '文章id',
  `news_title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章名称',
  `account_id` int NOT NULL COMMENT '公众id',
  `account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号名称',
  `original_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '原视频url',
  `cover` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  `vid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  `width` int NOT NULL COMMENT '视频宽度',
  `height` int NOT NULL COMMENT '视频高度',
  `video_quality_level` int NOT NULL COMMENT '视频级别',
  `video_quality_wording` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '清晰度',
  `qiniu_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '七牛转存url',
  `insert_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '插入时间',
  `is_delete` int DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='视频';

(5) news_content: tabla de contenido de noticias


CREATE TABLE `news_content` (
  `id` int NOT NULL AUTO_INCREMENT,
  `news_id` int NOT NULL,
  `news_title` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8_general_ci DEFAULT NULL,
  `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
  `insert_time` datetime DEFAULT NULL,
  `source` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  `is_delete` int DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `news_id` (`news_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='文章详情表';

(6) account_token: la tabla utilizada para almacenar el fondo de la cuenta


CREATE TABLE `account_token` (
  `id` int NOT NULL AUTO_INCREMENT,
  `account` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号名称',
  `token` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录token',
  `update_time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'token更新时间',
  `freq_control_time` datetime DEFAULT NULL,
  `is_delete` int DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='采集所用账号token';

3. Diseño de submódulos

(1) Obtener información básica del artículo a través de la automatización, como: imagen de portada, enlace de acceso al artículo, tiempo del artículo, etc.

(2) Abrir automáticamente el enlace del artículo para obtener la dirección del video contenido en el artículo. Hay dos tipos de videos en los detalles del artículo:

R. Los videos ordinarios para los detalles del artículo generalmente se pueden analizar y descargar directamente (los videos más regulares en los detalles del artículo a continuación):

imagen

B. El video TX insertado en los detalles del artículo está en formato m3u8. Debe descargar el archivo ts para sintetizar mp4. Si es un video TX, primero debe hacer clic en el botón de reproducción al automatizar, de lo contrario no podrá para obtener la dirección m3u8:

Los dos métodos de procesamiento de video son diferentes. Mi idea de procesamiento es: todos los artículos están conectados a la automatización, y se usa selenio para mostrar y esperar. Si encuentra un botón de video, haga clic en él y luego obtenga todos los datos solicitados para su posterior análisis.

(3) Solicite directamente la dirección del artículo original y analice el contenido a través de bs4 y lxml

  A. Eliminar el formato no deseado

  B. Transferir la imagen a Qiniu (reemplazar la imagen en el contenido original después de la transferencia)

  C. Extraiga la etiqueta de video original (debe reemplazarla después de que el video se descargue y transfiera a Qiniu y se transcodifique más tarde)

  D. Extraiga otras etiquetas, como fuente de noticias, editor, reportero y otros campos

(4) Dado que la cuenta está prohibida, puede considerar unirse a una cuenta. Una vez que la cuenta esté prohibida, cierre sesión en la cuenta actual, inicie sesión con una nueva cuenta y envíe el código QR de inicio de sesión a DingTalk para escanear

  A. Durante la automatización, la cuenta está bloqueada y no hay datos al consultar artículos, y la interfaz regresa con un mensaje de "control de frecuencia"

     B. Cuando la cuenta está prohibida, inserte un registro en la tabla y actualice el tiempo de prohibición. Al recuperar la cuenta, se determina que el tiempo de prohibición es superior a 1 hora.

  C. De hecho, qué cuenta se usa depende de quién esté escaneando con el teléfono móvil. El navegador tiene un caché de inicio de sesión. Antes de que se bloquee la cuenta, hemos estado usando el caché del navegador. De esta manera, cuando está automatizado, no tienes que escanear el código QR cada vez. Sí, hablaré de eso más adelante.

  D. Cuando necesite iniciar sesión, envíe la captura de pantalla del código QR al grupo DingTalk. Aquí, el tiempo de espera de automatización de la página se puede configurar más, como 10 minutos.

  Clasificación del módulo principal:

imagen

 Código compartido parcial:

1 Obtenga el método principal del artículo:


def get_news_main():
    """
    获取文章
    :return:
    """

    # 查询需要的号
    wei_account = read_sql.deal_mysql("get_account.sql")
    max_patch = read_sql.deal_mysql("get_max_patch.sql")[0][0]

    if max_patch is None:
        max_patch = 1
    else:
        if len(wei_account) == 0:
            max_patch = max_patch + 1
            wei_account = read_sql.deal_mysql("get_account_all.sql")
    for i in wei_account:
        # now() > DATE_ADD(freq_control_time, INTERVAL 1 HOUR) // 这里获取没有被封禁的账号继续执行任务
        crawl_account_l = read_sql.deal_mysql("get_account_token.sql")
        if crawl_account_l:
            # 随机取一个用于爬取的账号
            crawl = random.randrange(len(crawl_account_l))
            # 所用来爬取账号的id
            crawl_account_id = crawl_account_l[crawl][0]
            # 所用来爬取账号的账号
            crawl_account = crawl_account_l[crawl][1]
            # # 所用来爬取账号的登录token
            crawl_token = crawl_account_l[crawl][2]
            # 待爬取的账号id
            account_id = i[0]
            # 待爬取的账号名称
            account_name = i[1]
            # 需要爬取的页数   //为1爬取两页,0开始
            page = 0
            # 自动化操作路径
            driver = news.get_news(crawl_token, account_name, page, crawl_account_id, crawl_account)
            try:
                time.sleep(1)
                # 获取文章数据
                news_data, freq = analyze_news.analyze_news(driver)
                # 数据插入数据库
                in_news.insert_news(account_id, account_name, news_data)
                # 获取了的账号存入run_account表
                in_run.insert_run_account(account_id, account_name, max_patch)
                # 如果账号被封禁则更新被禁时间,并退出当前账号
                if freq is True:
                    ua.update_account_token_freq(crawl_account_id)
                    # 被封禁的账号退出登录
                    driver = lg.login_out(driver)
            except Exception as e:
                print(e)
            finally:
                driver.quit()
        else:
            print('账号封禁中,暂不能执行任务!!')
            break

 (1) Método de adquisición automática


# -*- coding = utf-8 -*-
# ------------------------------
# @time: 2022/5/5 17:11
# @Author: drew_gg
# @File: get_wei_chat_news.py
# @Software: wei_chat_news
# ------------------------------

import os
import time
import random
import configparser
from seleniumwire import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from get_news import get_login_token as gt
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

pl = os.getcwd().split('wei_chat_news')
# chromedriver地址
driver_path = pl[0] + "wei_chat_news\\charomedriver\\chromedriver.exe"
# 主配置文件地址
config_path = pl[0] + "wei_chat_news\\common_config\\main_config.ini"
config = configparser.ConfigParser()
config.read(config_path)


def get_news(token, account_name, page_num, crawl_account_id, crawl_account):
    """
    获取新闻
    :param token: 登录后token
    :param account_name: 获取文章的账号
    :param page_num: 获取文章的页数
    :param crawl_account_id: 用于获取的账号id
    :param crawl_account: 用于获取的账号
    :return:
    """
    # ************************************************** #
    # 由于微信账号的限制,一个账号只能爬取60页的数据,封禁1小时!!
    # ************************************************** #

    # seleniumwire:浏览器请求分析插件
    # 浏览器缓存文件地址(谷歌浏览器)
    profile_directory = r'--user-data-dir=%s' % config.get('wei_chat', 'chromedriver_user_data')

    # *******配置自动化参数*********#
    options = webdriver.ChromeOptions()
    # 加载浏览器缓存
    options.add_argument(profile_directory)
    # 避免代理跳转错误
    options.add_argument('--ignore-certificate-errors-spki-list')
    options.add_argument('--ignore-ssl-errors')
    options.add_argument('--ignore-ssl-errors')
    # 不打开浏览器运行
    # options.add_argument("headless")
    # *******配置自动化参数*********#

    driver = webdriver.Chrome(executable_path=driver_path, options=options)
    # 最大化浏览器
    driver.maximize_window()
    wei_chat_url = config.get('wei_chat', 'wei_chat_url') + token
    # 微信账号地址
    driver.get(wei_chat_url)
    try:
        # 点击草稿箱  //如果找不到则认为是没有登录成功
        WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.XPATH, "//a[@title='草稿箱']"))).click()
    except Exception as e:
        # 调用扫码登录
        driver = gt.get_login_token(driver, wei_chat_url, crawl_account_id, crawl_account)
        print(e)
    try:
        # 点击草稿箱
        WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.XPATH, "//a[@title='草稿箱']"))).click()
        # 点击“新的创作”
        WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.CLASS_NAME, "weui-desktop-card__icon-add"))).click()
        # 点击“写新图文”
        WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.CLASS_NAME, "icon-svg-editor-appmsg"))).click()
        time.sleep(1)
        # 切换到新窗口
        driver.switch_to.window(driver.window_handles[1])
        # 点击“超链接”
        WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.ID, "js_editor_insertlink"))).click()
        # 点击“其他账号”
        WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.XPATH, "//button[text()='选择其他账号']"))).click()
        # 输入“账号名称”
        driver.find_element(By.XPATH, value="//input[contains(@placeholder, '微信号')]").send_keys(account_name)
        # 回车查询
        driver.find_element(By.XPATH, value="//input[contains(@placeholder, '微信号')]").send_keys(Keys.ENTER)
        # 点击确认账号
    # 吃掉本次异常,不影响后续任务
    except Exception as e:
        print(e)
    try:
        e_v = "//*[@class='inner_link_account_nickname'][text()='%s']" % account_name
        WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.XPATH, e_v))).click()
    except Exception as e:
        ee = e
        print('没有该账号:', account_name)
        return driver
    for i in range(page_num):
        time.sleep(random.randrange(1, 3))
        try:
            WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.XPATH, "//a[text()='下一页']"))).click()
            try:
                # 暂无数据 //可能该账号没有文章,也可能被封了,直接返回!
                no_data_e = "//div[@class='weui-desktop-media-tips weui-desktop-tips'][text()='暂无数据']"
                nde = WebDriverWait(driver, 5, 0.2).until(EC.presence_of_element_located((By.XPATH, no_data_e)))
                if nde:
                    return driver
            except Exception as e:
                ee = e
        except Exception as e:
            ee = e
            return driver
    return driver

Supongo que te gusta

Origin blog.csdn.net/m0_73409141/article/details/131773677
Recomendado
Clasificación