Ejercicio del rastreador de Python: rastreo de información de formularios basado en XPath

Este es un ejercicio introductorio para los rastreadores de Python. Solicitamos datos a través de Request, hacemos coincidir los elementos o el contenido de la tabla a través de XPath y usamos Pandas para organizar los datos. Hagamos esto paso a paso.

Determinación de objetivos y análisis de ideas.

Objetivo

El objetivo es extraer datos tabulares de un sitio web. El sitio que he elegido es: http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaList(Lo siguiente también se puede llamar la página de lista).

  • Aquí hay una biblioteca de listas que contiene información personal, incluido el nombre, el nombre de la unidad, etc.
  • La lista está dividida en páginas, y debe seguir haciendo clic en la página siguiente para cargar más información.
  • Para obtener más información, debe hacer clic en el nombre de la lista para ingresar a la subpágina (en adelante, la página de detalles) para ver. Requiere clics circulares y rastreo secundario.

tren de pensamiento

La idea es que obtengamos todos los enlaces de la página de detalles correspondientes a cada persona a través de la selección de XPath y el cambio de página en la página de lista. Luego, recorra el enlace de la página de detalles, rastree la información y guárdela como un archivo csv.

observar la situación

Presione F12 para abrir las herramientas de desarrollo del navegador y seleccione la página Red.

Actualice la página de la lista, puede ver el flujo de información, incluida la URL de solicitud y los encabezados de solicitud, etc. Debido a que es un inicio de sesión con contraseña, necesitamos cookies como información de encabezado al enviar solicitudes.

Haga clic en la segunda página de la página de la lista, y encontramos que para pasar la página, solo necesitamos modificar el contenido después de la URL del enlace page=: http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaList?pinqing_dwdm=80002&is_yw=False&page=xxx.

Borre el flujo de información de la red, haga clic en un nombre a voluntad y abra la página de detalles correspondiente al cambio de nombre. Observe que su URL de solicitud es: http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaEdit?zhuanjia_id=xxxxx. Solicita información en forma de get, y zhuanjia_id corresponde al ID de cada persona, siempre que se cambie el ID, se devolverá la información de diferentes personas. Es fácil ver que la información de identificación se puede encontrar en el href de la columna de nombre en la página de lista.

Lo probé, y es problemático leer tablas en línea y operaciones básicas de formato de datos a través de pandas.read_html de pandas, así que uso directamente XPath para localizar.

tabla de lista de rastreo

De acuerdo con las ideas anteriores, procederemos en dos pasos, primero usaremos la página de lista y resumiremos la información en la página de detalles correspondiente a todos pasando la página. Se puede observar que

Después de escribir los encabezados, devuelva la información de la página web a través de requestes.get y luego use Xpath para extraer y archivar.

el código se muestra a continuación:

import requests
from lxml import etree
import pandas as pd
# parameter = {
    
    
#             "key1":"value1",
#             "key2":"value2"
#             }
headers = {
    
    "Cache-Control": "max-age=0",
           "Connection":"keep-alive",
           "Cookie":"xxxxxxxxxx",
           "Referer":"http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaList?pinqing_dwdm=80002&is_yw=False&page=2",
           "Upgrade-Insecure-Requests":"1",
           "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
    }
total_page = 2111
dfs = pd.DataFrame(columns=['name','id']);
ind = 0
for i in range(2111,total_page+1):
    response = requests.get("http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaList? \
                            pinqing_dwdm=80002&is_yw=False&page="+str(i), \
                            headers = headers)#,params = parameter)
    # print(response.url)
    # print(response.text)
    # print(response.content)
    # print(response.encoding)
    # print(response.status_code)
    html=response.text
    tree=etree.HTML(html)
    NAME = tree.xpath('//*[@id="main-content"]/div/div/div/div/div[2]/div/table/tbody/tr/td[1]/a')
    IDHREF = tree.xpath('//*[@id="main-content"]/div/div/div/div/div[2]/div/table/tbody/tr/td[1]/a/@href')
    for j in range(0,len(NAME)):
        ind = ind+1
        print(ind)
        ids = str(IDHREF[j]).split('=')
        new = pd.DataFrame({
    
    'name':NAME[j].text, 'id':int(ids[1])},index=[ind])
        dfs=dfs.append(new) 
dfs.to_csv("./教授名字和ID.csv", encoding="utf_8_sig")

No hay nada especial que enfatizar aquí, pero este código no tiene un rendimiento muy alto y hay muchos lugares que se pueden optimizar, como solo un árbol.xpath.

Rastrear la información secundaria de la página de detalles

Suponiendo que hayamos obtenido el ID necesario para rastrear la página de detalles, en este momento podemos obtener toda la información de la página de detalles enviando continuamente solicitudes a direcciones URL ligeramente diferentes. Luego, haga clic con el botón derecho en la herramienta de copia de XPath a través de la herramienta de desarrollo para obtener el modo de coincidencia de XPath, pegue y extraiga la información, organícela a través de Pandas y archívela. El código utilizado es el siguiente:

import requests
from lxml import etree
import pandas as pd
ID1 = pd.read_csv('./教授名字和ID0.csv')
ID2 = pd.read_csv('./教授名字和ID.csv')
ID1n = list(map(int, ID1['id'])) 
ID2n = list(map(int, ID2['id'])) 
IDs = ID1n+ID2n
IDs.sort()

header = {
    
    "Connection": "keep-alive",
"Cookie": "xxxx",
"Host": "py.ucas.ac.cn",
"Referer": "http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaList?pinqing_dwdm=80002&is_yw=False&page=1936",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
}
bg = 20617;
ed = len(IDs)
#ed = 2
data = pd.DataFrame(columns=['姓名','性别','单位','通讯地址','邮编','邮箱','手机',\
                             '固话','出生日期','身份证号','学科专业','方向','导师类别',\
                                 '专业技术职务','银行户头','银行地址','银行号码'])
count = -1
for i in range(bg,ed):
    count = count+1
    id = IDs[i]
    print(str(IDs[bg])+"TO"+str(IDs[ed-1])+":"+str(i)+":"+str(id)+"进行中...")
    response = requests.get("http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaEdit?zhuanjia_id="+str(id),headers=header)
    html=response.text
    # print(html)
    # with open('test.html','w',encoding='utf-8') as f:
    #     f.write(html)
    tree=etree.HTML(html)
    zjxm = str(tree.xpath('//*[@id="ZJXM"]/@value')[0]) #姓名
    zjxb = str(tree.xpath('//*[@id="ZJXB"]/option[@selected="selected"]/@value')[0])#性别
    jsdw = str(tree.xpath('//*[@id="DWDM"]/option[@selected="selected"]')[0].text)#单位
    zjtxdz = str(tree.xpath('//*[@id="ZJTXDZ"]/@value')[0])#通讯地址
    zjyzbm = str(tree.xpath('//*[@id="ZJYZBM"]/@value')[0])#邮编
    UserName = str(tree.xpath('//*[@id="UserName"]/@value')[0])#邮箱
    zjsj = str(tree.xpath('//*[@id="ZJSJ"]/@value')[0])#手机
    zjtel = str(tree.xpath('//*[@id="ZJTEL"]/@value')[0])#固话
    zjcsrq = str(tree.xpath('//*[@id="ZJCSRQ"]/@value')[0])#出生日期
    zjhm = str(tree.xpath('//*[@id="zjhm"]/@value')[0])#身份证号
    tmp = tree.xpath('//*[@id="ZJ_XKZY"]/option[@selected="selected"]')
    if len(tmp)==0:
        zjxkzy = ''
    else:
        zjxkzy = str(tmp[0].text)#学科专业
    yjfx = str(tree.xpath('//*[@id="yjfx"]/@value')[0])#方向  
    zjlb = str(tree.xpath('//*[@id="ZJLB"]/option[@selected="selected"]')[0].text)#导师类别
    tmp = tree.xpath('//*[@id="ZJZWCODE"]/option[@selected="selected"]')
    if len(tmp)==0:
        zjzwcode = ''
    else:
        zjzwcode = str(tmp[0].text)#专业技术职务  
    bank_hutou = str(tree.xpath('//*[@id="bank_hutou"]/@value')[0])#银行户头
    bank_dizhi = str(tree.xpath('//*[@id="bank_dizhi"]/@value')[0])#银行地址
    bank_xingming = str(tree.xpath('//*[@id="bank_xingming"]/@value')[0])#银行号码
    data.loc[count] = [zjxm,zjxb,jsdw,zjtxdz,zjyzbm,UserName,zjsj,zjtel,zjcsrq,zjhm,zjxkzy,yjfx,zjlb,zjzwcode,bank_hutou,bank_dizhi,bank_xingming]
data.to_csv("./"+str(bg)+"_"+str(IDs[bg])+"TO"+str(i)+"_"+str(IDs[i])+"高校教授联系方式.csv", encoding="utf_8_sig")

Sabemos que siempre habrá algunos problemas al rastrear durante mucho tiempo, como el rechazo de la red. En mi código, no hay captura de excepción en el modo de prueba. Cuando adopté el método de manejo de excepciones, el código se rompió y los resultados intermedios se guardaron manualmente primero. A continuación, vuelva a ejecutar manualmente el código desde el punto de interrupción.
Disfruto el proceso de transmisión manual sin ningún mecanismo de manejo de excepción.

Los reptiles cumplen con las leyes y regulaciones pertinentes y no cometen actos ilegales o delictivos.

Los reptiles están bien escritos y puedes comer todo lo que quieras. No rastree datos privados, no bloquee el sitio web. No use el método del rastreador para obtener ganancias.

Resumen de sugerencias para rastreadores

  1. La información del encabezado de la Solicitud se puede copiar y modificar directamente desde el flujo de información de la herramienta del desarrollador del navegador.

  2. Al hacer coincidir la información, se recomienda guardar una página web devuelta por la solicitud de Python para su análisis, en lugar de acceder directamente a la dirección de la solicitud en el navegador y hacer la coincidencia de elementos en función del resultado devuelto. Porque a veces los resultados obtenidos por las solicitudes de Python son diferentes de los obtenidos por las solicitudes del navegador. El ejemplo de código para guardar los resultados de la página web devueltos por Python es el siguiente:

    response = requests.get("http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaEdit?zhuanjia_id="+str(id),headers=header)
    html=response.text
    print(html)
    with open('test.html','w',encoding='utf-8') as f:
    	f.write(html)
    
  3. Botón derecho del mouse, verifique el elemento, copie XPath para obtener el patrón de coincidencia de XPath y péguelo en la interfaz de código. Pero cuando el resultado de la búsqueda está vacío o es incorrecto, puede copiar el XPath a la unidad hermana del elemento que está buscando para compararlo y analizarlo.

  4. Bueno en XPath @ funciones. Cuando vamos a XPath para obtener el valor del elemento en la etiqueta, podemos usar @ para obtener el valor, como: los corchetes tree.xpath('//*[@id="DWDM"]/option[@selected="selected"]')[0].textaquí representan el índice, option[@selected="selected"]lo que significa seleccionar el que cumple las condiciones en todas las opciones ( aquí es generado por el cuadro desplegable). Otro ejemplo es /@valor tree.xpath('//*[@id="ZJXM"]/@value')[0]en el que significa //*[@id="ZJXM"]tomar el valor de valor en todos para formar una lista.

  5. Organice una plantilla de Request+XPath de la siguiente manera, cada vez que desee rastrear algo, simplemente cópielo y modifíquelo para usarlo:

    import requests
    from lxml import etree
    import pandas as pd
    # parameter = {
          
          
    #             "key1":"value1",
    #             "key2":"value2"
    #             }
    header = {
          
          "Connection": "keep-alive",
    "Cookie": "xxx",
    "Host": "py.ucas.ac.cn",
    "Referer": "http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaList?pinqing_dwdm=80002&is_yw=False&page=1936",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
    }
    data = pd.DataFrame(columns=['姓名','单位'])
    response = requests.get("http://py.ucas.ac.cn/zh-cn/zhuanjia/ZhuanjiaEdit?zhuanjia_id=xxx",headers=header)#,params = parameter)
    html=response.text
    print(html)
    # print(response.url)
    # print(response.text)
    # print(response.content)
    # print(response.encoding)
    # print(response.status_code)
    with open('test.html','w',encoding='utf-8') as f:
        f.write(html)
    tree=etree.HTML(html)
    zjxm = str(tree.xpath('//*[@id="ZJXM"]/@value')[0]) #姓名
    jsdw = str(tree.xpath('//*[@id="DWDM"]/option[@selected="selected"]')[0].text)#单位
    data.loc[0] = [zjxm,jsdw]
    data.to_csv("xxx.csv", encoding="utf_8_sig")
    

Supongo que te gusta

Origin blog.csdn.net/lusongno1/article/details/128195834
Recomendado
Clasificación