Cómo usar Python para capturar datos de Douban Reading
El primer paso es comprobar las bibliotecas que necesitamos:
¿Solicitud de importación? #Se utiliza para solicitar páginas web
Importar BeautifulSoup desde bs4 #Analizar páginas web
¿Tiempo de importación? #Establezca un tiempo de retraso para evitar que los números IP bloqueados se busquen con demasiada frecuencia.
Importar re #biblioteca de expresiones regulares
¿Importar pymysql? #Debido a que hay demasiados datos rastreados, debemos almacenarlos en la base de datos MySQL para conectarnos a la base de datos.
Importar aleatorio #Esta base de datos utiliza la función randint para generar números aleatorios que coincidan con el tiempo anterior para que el intervalo de rastreo sea aleatorio.
Este es el sitio web de Douban: x-sorttags-all.
Queremos obtener todos los enlaces de etiquetas de categorías desde aquí y capturar aún más la información que contiene. Primero publique el código:
Solicitud de importación
¿Importar BeautifulSoup desde bs4? #Importar biblioteca
url="httom/tag/?icn =index navegación"
Wb_data=requests.get(url) #Solicitar URL
sopa = hermosa sopa(WB_data.text,"lxml")? #Analizar información de la página web
tags = sopa select(" # content gt; div gtdiv.article gtdiv gtdiv gt table gttbody gttr gttd gt one")
#Buscar etiquetas basadas en Información de ruta CSS, método de adquisición de ruta CSS, selector de copia, inspección y clic derecho, lista de devolución de etiquetas.
Para etiquetas en etiquetas:
Tag=tag.get_text() #Extrae información para cada etiqueta en la lista.
helf="hom/tag/"
#Mirando el sitio web de Douban, básicamente esta parte tiene etiquetas de información, por lo que necesitamos crear un sitio web que capture la página de detalles de la etiqueta.
url=helf str(tag)
Print(url) # La URL se ensambla y se genera.
Arriba, rastreamos todas las URL bajo la etiqueta. Llamamos canal a este archivo, creamos una cadena de canal en el canal e ingresamos toda la información de la URL que rastreamos. Cuando rastreamos la página de detalles, podemos extraer directamente el enlace desde aquí, de la siguiente manera:
. Canal = ' ' '
Etiqueta/Programa
'''
Ahora, comencemos el segundo programa.
QQ Picture 20160915233329.png
La información de cada imagen debajo de la pestaña es básicamente la misma. Podemos extraer directamente el título del libro, autor, editorial, tiempo de publicación, precio, número de revisores, calificaciones y otra información desde aquí (algunas obras extranjeras también tendrán información del traductor). El método de extracción es similar al de la pestaña y también se extrae según la ruta CSS.
Primero utilizamos un sitio web para experimentar con el rastreo:
URL = " http/tag/technology "
wb_data = request.get(url) p> p>
sopa = sopa hermosa(WB_data . text . encode(" utf-8 "), " lxml ")
tag=url.split("?) [0].split ("/")[-1] #Extraiga la información de la etiqueta del enlace para facilitar el almacenamiento
detils = sopa select(" # sujeto _ lista gt;ul gt李gtdiv.info gtdiv.pub "; info gtdiv star . clear fix gt;span.rating_nums ")? #Obtener información de puntuación
personas = sopa . select(" # sujeto _ lista gt;ul gt李gtdiv.info gtdiv . star . clear fix gt; Span.pl") #El número de personas evaluadas
titles = sopa. select(" # sujeto _ lista gt; ul gt李gtdiv.info gth2 gta")? #Títulos p>
#Lo anterior es toda la información de etiquetas html que necesitamos, que debe separarse una por una.
Para detalles, puntuación, personal y títulos en el zip:
.#Utilice la función zip() para implementar el recorrido
#Debido a que algunas etiquetas tienen información del traductor y otras no, para evitar errores, debemos separarlas con un intento
# p>
Prueba:
autor = detil.get_text().split()[0] #Este es un método de extracción de información, divide la etiqueta en cinco partes. según "/", y luego extráigalos uno por uno
Yizhe = split("/", 4)[1]
publish=detil.get_text(). split("/", 4) [2]
time=detil.get_text(). dividir("/",4)[3]. dividir()[0]. split("-"[0]? #Solo extraemos la hora del año de publicación.
Precio = Shi Ce_priceone(detil) #Debido a que la unidad de precio no es uniforme, usamos una función para convertir " Yuan".
SCOE = SCOR. GET _ TEXT () si es verdadero, sino ""#Para evitar errores, configuramos la información sin clasificar en blanco. >
人=Shi Ce_人(人) ? #Algunos libros tienen menos de 10 revisores y se producirá un error durante el proceso de rastreo
title=title .get_text().split()[0]. #Cuando no haya información del traductor, se mostrará IndexError y lo manejaremos por separado.
Excepto error de índice:
Prueba:
author=detil.get_text(). dividir("/",3)[0]. Split()[0]
Yizhe="" #Divida la información detallada en cuatro partes para extraer, configure directamente la información del traductor en vacía y las demás son las mismas que las anteriores.
publicar=detil.get_text(). split("/", 3)[1]
time=detil.get_text(). dividir("/",3)[2]. dividir()[0]. Split("-"[0])
Precio=Shi Ce_Price 2 (Detalles)
scoe=scor.get_text() si es Verdadero, sino " "
人=Shi Ce_人(人)
title=title.get_text(). split()[0]
excepto (IndexError, TypeError):
¿Continuar?
#Si aparecen otros mensajes de error, ignórelo y continúe con la ejecución (parte de la información bibliográfica no tendrá el editor ni el año de publicación, pero el número es muy pequeño y no afectará nuestro rastreo a gran escala, así que simplemente ignorarlo).
Salvo error de tipo:
Continuar
#Función para extraer el número de revisores. Si el número de evaluadores es inferior a diez, se considerará diez.
def Shi Ce_person(人):
Pruebe:
persona = int(persona.get_text().split()[0][1:len (persona . get_text().split()[0]) - 4])
Excepto error de valor:
persona = int(10)
Retornador
#Función para extraer precios por caso, buscar información con caracteres especiales mediante expresiones regulares y convertirla a "yuanes".
def Shi Ce_price (precio):
precio = detil.get_text(). dividir("/",4)[4]. split()
if rematch(" USD ", precio[0]):
precio = float(precio[1]) * 6
elif re .match("CNY ", precio[0]):
Precio=precio[1]
elif re.match("\A$ ", precio[0] ):
Precio = float(Precio[1:len(Precio)]) * 6
En caso contrario:
Precio = Precio[0]
Precio de retorno
def Shi Ce_pricetwo(precio):
precio = detil.get_text(). dividir("/",3)[3]. split()
if rematch(" USD ", precio[0]):
precio = float(precio[1]) * 6
elif re .match("CNY ", precio[0]):
Precio=precio[1]
elif re.match("\A$ ", precio[0] ):
Precio = float(Precio[1:len(Precio)]) * 6
En caso contrario:
Precio = Precio[0]
Precio de retorno
Una vez que el experimento sea exitoso, podemos capturar los datos e importarlos a la base de datos. El siguiente es el código fuente completo, con comentarios para casos especiales.
Importar solicitud
Importar BeautifulSoup desde bs4
Importar hora
Importar re
Importar pymysql
¿Importar canales desde canales? #Esta es la información del enlace capturada por nuestro primer programa.
Importación aleatoria
def Shi Ce_person(persona):
Pruebe:
persona = int(persona.get_text() .split ()[0][1: len(persona . get_text().split()[0]) - 4])
excepto error de valor:
persona = int(10 )
Retornado
def Shi Ce_price (precio):
precio = detil.get_text(). dividir("/",4)[4]. split()
if rematch(" USD ", precio[0]):
precio = float(precio[1]) * 6
elif re .match("CNY ", precio[0]):
Precio=precio[1]
elif re.match("\A$ ", precio[0] ):
Precio = float(Precio[1:len(Precio)]) * 6
En caso contrario:
Precio = Precio[0]
Precio de retorno
def Shi Ce_pricetwo(precio):
precio = detil.get_text(). dividir("/",3)[3]. split()
if rematch(" USD ", precio[0]):
precio = float(precio[1]) * 6
elif re .match("CNY ", precio[0]):
Precio=precio[1]
elif re.match("\A$ ", precio[0] ):
Precio = float(Precio[1:len(Precio)]) * 6
En caso contrario:
Precio = Precio[0]
Precio de retorno
#Esta es la función de prueba anterior, la colocamos en la función principal.
Definir potencia (url):
wb_data = request.get(url)
sopa = sopa hermosa(WB _ data . text . encode(" utf -8 ")," lxml ")
tag=url.split("?)[0].split("/")[-1]
detils = sopa . select(" # materia _ lista gt;ul gt李gtdiv.info gtdiv.pub ")
scors = sopa .select(" # materia _lista gt;ul gt李gtdiv.info gtdiv.star . clear fix gt; span.rating_nums ")
personas = sopa . select(" # sujeto _ lista gt; ul gt李gtdiv.info gtdiv . star . clear fix gt; span.pl ")
títulos = sopa . select(" # asunto _ lista gt;ul gt 李gtdiv.info gth2 gt a")
Para detalles, scor, personal, títulos en zip (Detalles, SCOR, Personal, Título):
l = []? #Crear una lista de datos almacenados
author=detil.get_text ().split("/",4)[ 0]. dividir()[0]
yizhe = detil.get_text() /p>
publicar=detil.get_text(). /p>
time=detil.get_text(). [3]. split()[0]. split("-"[0])
Precio = Precio Scoe (detalles) p>
scoe=scor.get_text() si es Verdadero else " "
人=Shi Ce_人(人)
title=title.get_text() split() [0]
Excepto error de índice:
Intente:
author=detil.get_text(). dividir("/",3)[0]. split()[0]
Yizhe = " "
publish=detil.get_text(). split("/", 3)[1]
time=detil.get_text(). dividir("/",3)[2]. dividir()[0]. Split("-"[0])
Precio=Shi Ce_Price 2 (Detalles)
scoe=scor.get_text() si es Verdadero, sino " "
人=Shi Ce_人(人)
title=title.get_text().
split()[0]
excepto (IndexError, TypeError):
¿Continuar?
Excepto error de tipo:
Continuar
l append([título, alcance, autor, precio, hora, publicación, persona, Yi Zhe, etiqueta] )
#Complete los datos rastreados en la lista por turno.
SQL = "INSERTAR EN todos los valores contables (s, s, s, s, s, s, s, s, s)"? #Esta es una declaración de inserción SQL.
cur.executemany(sql,l)? #Ejecute sentencias SQL e insértelas en la base de datos en lotes usando la función ejecutarmary().
conn.commit()
#La función principal termina aquí.
#Conectar Python a la base de datos Python en MySQL.
conn = pymysql . connect(usuario = " root ", contraseña = " 123123 ", base de datos = " python ", charset = 'utf8 ')
cur = conn. )
cur ejecutar('DROP TABLE SI existen todos los libros')? #Si hay una base de datos de todos los libros en la base de datos, elimínela.
sql = " "Crear tabla allbooks(
El carácter del título (255) no está vacío,
cargador scor (255),
Autor CHAR(255),
Precio CHAR(255),
Cargador de tiempo (255),
Carácter de publicación (255),
p>Encargado(255),
Yizhe Shire(255),
Personaje de etiqueta(255)
)"" "
cur .execute(sql)?#Ejecute la instrucción sql y cree una nueva base de datos de todos los libros.
start = time.clock()?#Establezca un reloj para que pueda saber cuánto tiempo rastreado
Para la URL en canal.split():
urlss=[urls "? start = { } amptype=T”.format(str(i)) for i in range(0, 980, 20)] #Extraer información de URL del canal y combinarla en enlaces para cada página. p>
Para la URL en urlss:
Contenido principal (dirección web)? #Ejecutar la función principal y comenzar a rastrear
Imprimir(url) #Salida a rastrear, entonces. que podemos conocer la posición de rastreo y manejar errores fácilmente.
time . se puede detener durante un período de tiempo aleatorio para evitar que se bloquee la IP
end = time.clock()
Print('Time Usage:', end-start) #Rastreo. Finalice y genere el tiempo de rastreo
count = cur . ? El número total de rastreos.
#Liberar conexión de datos
Si está doblado:
Actualmente cerrado()
Si está conectado:
conn .close()
De esta forma, incluso si se completa un programa, la información bibliográfica de Douban se escribirá en nuestra base de datos una por una. Por supuesto, también encontramos muchos problemas durante el proceso de rastreo, por ejemplo, habrá espacios en la información devuelta por el título después de la división y habrá errores al escribir en la base de datos, por lo que solo la primera parte del título. será interceptado, lo que provocará algunos problemas en la base de datos. Título incompleto. Por favor dígame si hay alguna manera de pasar.
La espera para gatear es larga y alegre. Al ver los mensajes escritos uno tras otro en la computadora, inconscientemente me vino a la mente una sensación de logro. Sin embargo, si gatea mientras estás comiendo, gatea mientras vas al baño y regresas de escalar una montaña, se congelará un poco mientras aún está subiendo, temiendo que la computadora se estropee en cualquier momento (aún así). los estudiantes pobres no pueden permitirse el lujo de reemplazarlo)
Por lo tanto, es mejor aprender a establecer puntos de interrupción, subprocesos múltiples y regularización. El camino es largo y largo, y el camino largo es Xi que exploro de arriba a abajo ~ * * * ~
.