Red de conocimiento informático - Aprendizaje de código fuente - Código fuente de Sina Weibo

Código fuente de Sina Weibo

0x00. Razón

Porque para participar en el concurso de innovación de estudiantes universitarios y estudiar las emociones expresadas en las publicaciones del blog de Weibo, se necesita una gran cantidad de publicaciones del blog de Weibo, ya sea un título nacional, CSDN o extranjero. Google, ni gayhub ni codeproject pudieron encontrar el programa que quería, así que tuve que escribir mi propio programa.

Hymn Encontré un programa similar en "Climbing Alliance", pero está en Windows y el código fuente está cerrado. Además, cuando rastreé los archivos guardados y los abrí con el bloc de notas, aparecieron muchos problemas extraños, así que me di por vencido.

0x001. Conocimientos básicos

Este programa está escrito en Python, por lo que se requieren conocimientos básicos de Python. Además, si tiene una determinada base de red informática, evitará muchos desvíos en los primeros preparativos.

Para los reptiles, es necesario aclarar los siguientes puntos:

1. La clasificación de los objetos rastreadores se puede dividir en las siguientes categorías: La primera categoría no requiere inicio de sesión, como por ejemplo. blogs Solía ​​subir a la Red Meteorológica de China cuando practicaba. Este tipo de página web es difícil de rastrear y se recomienda que los rastreadores novatos rastreen dichas páginas web; la segunda es iniciar sesión, como Douban y Sina Weibo, que es difícil de rastrear, y la tercera es independiente de las dos primeras; la información que desea generalmente se actualiza dinámicamente, como AJAX o recursos integrados. Este tipo de rastreador es el más difícil y no ha sido estudiado por los blogueros, por lo que no entraré en detalles aquí (según mis compañeros de clase, las reseñas de productos de Taobao entran en esta categoría).

2. Si la misma fuente de datos viene en múltiples formas (como versión para computadora, versión móvil, cliente, etc.), un método de presentación más "puro" es más popular. Por ejemplo, Sina Weibo tiene una versión web y una versión móvil, y se puede acceder a la versión móvil a través del navegador de una computadora. En este momento prefiero la versión móvil de Sina Weibo.

3. Los rastreadores generalmente descargan páginas web localmente y luego extraen información interesante de alguna manera. En otras palabras, rastrear la web es solo la mitad de la batalla: debe extraer la información que le interesa del archivo html descargado. En este momento, se necesitan algunos conocimientos de xml. En este proyecto, el blogger utiliza XPath para extraer información, pero también se pueden utilizar otras tecnologías como XQuery. Visite w3cschool para obtener más detalles.

4. Los reptiles deben imitar a los humanos tanto como sea posible. Ahora se ha desarrollado el mecanismo anti-rastreo del sitio web. Desde códigos de verificación hasta prohibiciones de IP, la tecnología de rastreo y la tecnología anti-rastreador pueden describirse como un juego continuo.

0x02. Ir

Después de determinar el objetivo del rastreador, primero debe visitar la página web de destino para comprender a cuál de los rastreadores anteriores pertenece la página web de destino. Además, registre los pasos que debe seguir para obtener la información que le interesa, como si necesita iniciar sesión y, de ser así, si se requiere un código de verificación, qué debe hacer para obtener la información que desea; , si necesita enviar algunos formularios; cuáles son las reglas para la URL de la página donde se encuentra la información que desea, etc.

La siguiente publicación de blog toma el proyecto de Blogger como ejemplo. Este proyecto captura todas las publicaciones de Weibo de un usuario específico de Sina Weibo desde el registro y captura 100 páginas de publicaciones de Weibo (aproximadamente 1000 artículos) por palabra clave.

0x03. Recopile la información necesaria

Primero visite la página web de destino y descubra que necesita iniciar sesión. Ingrese a la página de inicio de sesión de la siguiente manera: Página de inicio de sesión de la versión móvil de Sina Weibo.

Tenga en cuenta que hay muchos caracteres de escape como "xx" en la segunda mitad de la URL, que se analizarán más adelante en este artículo.

Como puede ver en esta página, debe ingresar su número de cuenta, contraseña y código de verificación para iniciar sesión en la versión móvil de Sina Weibo.

Este código de verificación solo debe proporcionarse recientemente (este artículo se creó el 11 de marzo de 2016). Si no necesita proporcionar un código de verificación, hay dos formas de iniciar sesión.

El primer método consiste en realizar una simulación js, completar la contraseña de la cuenta y hacer clic en el botón "Iniciar sesión". El blogger usó este método para escribir un rastreador de Java antes, pero ahora no se puede encontrar el proyecto, por lo que no entraré en detalles aquí.

El segundo método requiere una determinada base HTTP y envía una solicitud HTTP POST que contiene la información requerida.

Necesitamos la herramienta Wireshark para capturar los paquetes que enviamos y recibimos al iniciar sesión en Weibo. Como se muestra en la imagen a continuación, capturé los paquetes de datos enviados y recibidos al iniciar sesión. Wireshark obtuvo el resultado de 1.

Proporcione el criterio de búsqueda "/(displayID)?page=(pagenum)" en la barra de búsqueda. Esta será la base para que nuestro rastreador una las URL.

A continuación, observamos el código fuente de la página web para encontrar la ubicación de la información que queremos. Abra las herramientas de desarrollo del navegador y ubique directamente un Weibo para encontrar su ubicación, como se muestra a continuación.

xpath

Al observar el código html, encontramos que todos los Weibo están en la etiqueta

Además, hay algunos factores que requieren especial atención.

*Weibo se divide en Weibo original y Weibo reenviado.

*Dependiendo de la diferencia entre la hora de publicación y la hora actual, hay muchas formas de mostrar la hora en la página, como "Hace MM minutos", "HH de hoy: MM", "MM mes dd día HH:MM" -DD ​​hh:mm:SS". *La versión móvil de Sina Weibo muestra alrededor de 10 publicaciones de Weibo en una página, preste atención al número total* *.

0x04. Codificación

1. Capture al usuario Weibo

El lenguaje de desarrollo de este proyecto es Python 2.7. En el proyecto se utilizan algunas bibliotecas de terceros, que se pueden agregar a través de pip.

Dado que el código de verificación bloquea la idea del inicio de sesión automático, los usuarios solo pueden proporcionar cookies si desean acceder a la página de Weibo de un usuario específico.

El primero es el módulo de solicitud de Python, que proporciona cookies a las solicitudes de URL.

Solicitud de importación

Solicitud de impresión. obtener (url, cookies = cookies). El contenido utiliza este código para imprimir los resultados de la página de solicitud de URL con cookies.

Primero, obtenga el número de páginas de Weibo del usuario. Al verificar el código fuente de la página web, busque el elemento que representa el número de página y extraiga el número de página mediante tecnologías como XPath.

Número de páginas

Este proyecto utiliza el módulo lxml para extraer html a través de XPath.

Primero, importe el módulo lxml. Solo se utiliza etree en el proyecto, así que importe etree desde lxml.

Luego utilice el siguiente método para devolver el número de página.

def getpagenum(self):

URL = self . geturl(pagenum = 1)

html = request.get(url, cookies=self.cook ). Contenido#Visite la primera página para obtener el número de página.

Selector = etree. HTML(html)

pagenum = selector . XPath('//input[@ nombre = " MP "]/@ valor ')[0]

return int(pagenum)

El siguiente paso es unir continuamente la URL -> visitar la URL - gt;

Cabe señalar que debido a la existencia del mecanismo anti-rastreo de Sina, si la misma cookie visita la página con demasiada frecuencia, entrará en un "período de reflexión" similar, es decir, una página inútil. será devuelto. Al analizar esta página inútil, descubrimos que esta página tendrá información específica en un lugar específico. Si esta página es útil para nosotros se puede juzgar a través de la tecnología XPath.

def ispageneeded(html):

selector = etree.

HTML(html)

Pruebe:

título = selector . XPath('//título ')[0]

Excepto:

Devolver Falso

¡Devolver título.texto! = 'Plaza Weibo' y título.texto! = 'Weibo'

Si hay páginas inútiles, sólo tienes que visitarlas nuevamente. Sin embargo, a través de experimentos posteriores, se descubrió que si se accede a ellas con frecuencia durante mucho tiempo, las páginas devueltas serán inútiles y el programa caerá en un bucle infinito. Para evitar que el programa caiga en un bucle infinito, el blogger establece un umbral de cuenta de prueba. Una vez superado el umbral, el método regresará automáticamente.

El siguiente fragmento de código muestra el enfoque del rastreador de un solo subproceso.

def startcrawling(self, página de inicio=1, trycount=20):

try=0

prueba:

OS .mkdir (sys . ruta[0] '/Weibo _ raw/' self . deseado) excepto excepción, e:

Imprimir cadena(e)

isdone = False

mientras no está hecho e intenta contar:

prueba:

pagenum = self.getpagenum()

está hecho = True

Con excepciones, e:

try = 1

if try == trycount:

Return False

i = página de inicio

y i lt= pagenum:

try=0

isneeded=False

html=' '

mientras no isneeded e intenta contar lttry:

html = self . getpage(self . geturl(I))

isneeded = self . requerido:

intento = 1

si intento == trycount:

Devuelve Falso

self . guardar html (sys . ruta[. 0] '/Weibo _ raw/' self . wanted '/' str(I) '.txt ',html) print string(i) '/' string(pagenum - 1)

i = 1

Devuelve True

Teniendo en cuenta la eficiencia del tiempo del programa, después de escribir un rastreador de un solo subproceso, el blogger escribió una versión del rastreador de subprocesos múltiples. La idea básica es dividir el número de páginas de Weibo por el número de comentarios. Por ejemplo, un usuario en Weibo tiene 100 páginas de Weibo y el programa tiene 10 hilos, entonces cada hilo solo es responsable de rastrear 10 páginas. Las otras ideas básicas son similares a las del hilo único, solo los valores límite deben manejarse con cuidado, por lo que no entraré en detalles aquí. Además, debido a la eficiencia relativamente alta del subproceso múltiple y la gran cantidad de concurrencia, el servidor puede devolver fácilmente páginas no válidas, por lo que la configuración de trycount es más importante. Cuando el blogger escribió este Weibo, utilizó una nueva cookie para comprobar quién rastreaba el Weibo de la Universidad de Correos y Telecomunicaciones de Beijing. Se rastrearon con éxito los 3976 artículos de Weibo y se extrajeron las publicaciones del blog. Solo tomó 15 segundos, lo que en realidad puede estar relacionado con las cookies nuevas y antiguas y el entorno de red.

La configuración de la línea de comando es la siguiente. El significado de la línea de comando se explica en el sitio web del proyecto: python main.py _ T _ WM = xxxSUHB = xxxSUB = xxxGSID _ CTANDWM = XXX UBUPPT M 20 20 La introducción básica al trabajo de rastreo es. A continuación, analice el rastreador. Segunda parte. Debido a que el proyecto proporciona un método de rastreo de subprocesos múltiples, y los subprocesos múltiples generalmente no funcionan, pero las publicaciones del blog de Weibo están ordenadas por tiempo, el proyecto adopta un método de compromiso y guarda las páginas descargadas en el sistema de archivos local. La página tiene su número de página como nombre de archivo. Una vez finalizado el trabajo de rastreo, se recorren y analizan todos los archivos de la carpeta.

A través de las observaciones anteriores, entendemos las características de las publicaciones del blog de Weibo. Al utilizar la tecnología XPath, no es difícil extraer todas las etiquetas con este atributo de esta página.

En tercer lugar, Weibo se divide en Weibo reenviado y Weibo original, expresión de tiempo. Además, debido a que nuestro tema de investigación solo está interesado en el texto de Weibo, no se consideran las ilustraciones.

def startparsing(self, parsing time = datetime. datetime. now()):

basepath = sys path[0] '/Weibo _ raw/' uid para. nombre de archivo en OS . listdir(ruta base):

if nombre de archivo.startswith(' . '):

Continuar

ruta = ruta base '/' nombre de archivo

f = open(ruta, "r")

html = f.read()

selector = etree. HTML(html)

weiboitems = selector . XPath('//div[@ class = " c "][@ id]') se utiliza para elementos en elementos de Weibo:

Weibo = Weibo()

weibo.id = item.xpath('./@id')[0]

cmt = item.xpath('./div/ span[ @ clase = " CMT "]')si len(CMT)! = 0:

weibo.isrepost = Verdadero

weibo.content = cmt[0]. Texto

De lo contrario:

weibo.isrepost = False

ctt = item.xpath('./div/span[@class="ctt"]' )[0]

Si ctt.text no es Ninguno:

weibo.content = ctt.text

Para en ctt.xpath. /a '):

Si a.text no es Ninguno:

Weibo.content = a.text

Si a.tail no es Ninguno:

weibo.content = a.tail

si len(cmt)! = 0:

razón = CMT[1]. split(u '\xa0 ')

if len(razón)! = 1:

Weibo . reportstroy = motivo[0]

ct = item.xpath('.

/div/span[@class="ct"]')[0]

tiempo = ct.text.split(u'\xa0')[0]

weibo. time = self.gettime(self, time, parsingtime)self.weibos.append(Weibo.__Dictionary__)

f.close()

Parámetros pasados ​​por el método La intención original de configurar el tiempo de análisis es que el rastreo y el análisis no se pueden realizar al mismo tiempo en las primeras etapas de desarrollo (no "al mismo tiempo" en el sentido estricto, la visualización del tiempo de Weibo se basa en el tiempo de acceso). La hora son las 10:00 y se publicó hace cinco minutos. Se muestra una publicación de Weibo, pero si la hora de análisis es las 10:30, la hora de análisis será incorrecta. Por lo tanto, al final del desarrollo básico del rastreador. La diferencia de tiempo entre el tiempo de inicio del rastreo y el análisis se reducirá. La diferencia de tiempo es el tiempo del proceso de rastreo y básicamente se puede ignorar.

Los resultados del análisis se guardan en la lista. Finalmente, la lista se guarda en el sistema de archivos en formato json y se elimina la carpeta de conversión.

Definición save(self):

f = open(sys . path[0] '/Weibo _ parsed/' self . uid '. txt ', ' w ')JSON str = JSON . dumps(self . weibos, sangría=4, asegúrese de _ascii=False) f.write(jsonstr)

f.close()

Tomar palabras clave

Nuevamente, recopile la información necesaria. Ingrese "python" en la página de búsqueda móvil de Weibo, observe la URL y estudie sus patrones. Aunque la primera página no tiene reglas, encontramos una regla en la segunda página que se puede aplicar a la primera página.

Segunda página

Primera página después de la aplicación

Observando la URL, podemos encontrar que las únicas variables en la URL son palabras clave y páginas (de hecho, hideSearchFrame es muy útil para nosotros) los resultados de búsqueda y los rastreadores no tienen ningún efecto), por lo que podemos controlar estas dos variables en el código.

Además, si la palabra clave es china, la URL debe convertirse a caracteres chinos. Por ejemplo, si escribimos "Happy" en el cuadro de búsqueda para buscar, encontramos que la URL muestra Happy Search de la siguiente manera.

¿Pero se copia como

/search/mblog? hideSearchFrame = amp palabras clave = E5 BC 80 E5 BF 83 ampPage=1 Afortunadamente, la biblioteca urllib de Python tiene el método qoute para manejar la conversión al chino (si es inglés, no se convertirá), así que use este método para procesar los parámetros antes de empalmar URL.

Además, considerando que la búsqueda de palabras clave es un método utilizado en la etapa de recopilación de datos, aquí solo proporcionamos la descarga de páginas web con un solo hilo. Si necesita subprocesos múltiples, puede reescribirlo usted mismo de acuerdo con el método de subprocesos múltiples para capturar al usuario Weibo. Finalmente, extraiga y guarde la página web descargada (sé que el diseño de este módulo es un poco extraño, así que planeo cambiarlo cuando lo vuelva a crear (Hao), eso es todo).

rastreo de palabras clave def (self, palabra clave):

palabra clave real = URL lib quote(palabra clave) #Procesar palabras clave en chino.

Pruebe:

OS . mkdir(sys . path[0] '/keywords ')

Con excepciones, e:

Imprimir cadena (e)

Weibo = []

Prueba:

puntos altos = re . ]')# Procesa emoticones, pero parece que no funciona.

Excepto re.error:

puntos altos = re .compile(u '[\ud 800-\uDBFF][\UDC 00-\uDFFF]')pagenum = 0

es necesario = False

Cuando no es necesario:

html = self . get page('/search/mblog?keyword=s amppage = 1 'palabra clave real) es necesario = self . ispageneeded(html)

Si es necesario:

Selector = etree. HTML(html)

Pruebe:

pagenum = int(selector . XPath('//input[@ nombre = " MP "]/@ valor ')[0]) excepto :

pagenum = 1

Para el rango I(1, pagenum 1):

Pruebe:

es necesario = False

Cuando no es necesario:

html = self . get page('/search/mblog?keyword=s amppage=s' (realkeyword,str(I)))es necesario = self espageneeded. (html)

Selector = etree. HTML(html)

weiboitems = selector . XPath('//div[@ class = " c "][@ id]') se utiliza para elementos en elementos de Weibo:

cmt = item.xpath('./div/span[@ class = "CMT"]')if(len(CMT))= = 0:

ctt = item.xpath('./div /span[@class="ctt"]')[0]

Si ctt.text no es Ninguno:

texto = etree.tostring(ctt, método='texto ' , codificación = " unicode ") tail = CTT

if text.endswith(tail):

index = -len(tail)

text =. text[1:index]

text = highpoints.sub(u'\u25FD ', text) #La forma en que se procesan los emoticones no parece funcionar.

Texto de Weibo = texto

Anexo de Weibo (texto de Weibo)

Imprimir cadena (i) cadena '/' (pagenum)

Con excepciones, e:

Imprimir cadena(e)

f = open(sys . path[0] '/keywords/' palabra clave '.txt ' , 'w') Pruebe :

f.write(json.dumps(weibos, indent=4, sure_ ascii = False)) Excepción, por ejemplo:

Imprimir cadena (ex)

Finalmente:

f.close()

El blogger nunca antes había escrito ningún programa de rastreo. Para obtener publicaciones del blog de Sina Weibo, los blogueros escribieron tres programas de rastreo diferentes, incluidos Python y Java. Es normal que los reptiles no sean utilizables. No te desanimes. Los programas de rastreo y los mecanismos anti-rastreo compiten constantemente.

Además, informe al blogger al reimprimir. Si cree que el blogger es el jefe, no es necesario informarlo.