网页抓取的csv信息保存问题

时间:2020-07-25 04:34:28

标签: python csv math

我正在通过Web抓取从页面中检索信息,我的代码没有引发错误,但是我想将这些信息保存在一种数据库中时遇到了问题。我留下了代码,看是否有人可以帮助我,我创建了csv文件,但此刻,它绝对不保存任何内容:

import requests
from bs4 import BeautifulSoup
import csv
from urllib.request import urlopen

#MOTOR DE BUSQUEDA
#Rastreo de sitios a traves de la barra de búsqueda


class Content: #Pensamos las noticias como objetos o elementos, por ende creamos la clase Content para extraer el contenido del sitio "el ciudadano"
    def __init__(self, topic, url, title, body, data): #se crea de esta forma una clase, donde tenemos el titulo, el cuerpo, la url y el topico de búsqueda.
        self.topic = topic #leemos la palabra clave de búsqueda
        self.title = title #leemos el titulo
        self.body = body #leemos el cuerpo
        self.url = url #leemos la URL
        self.data = data #leemos la fecha de publicación
        
    def print(self):
        print("New article found for topic: {}".format(self.topic)) 
        print("TITLE: {}".format(self.title))
        print("BODY:\n{}".format(self.body))
        print("URL: {}".format(self.url))
        print("DATA: {}".format(self.data))
        
class Website: #Clase que guarda las propiedades del sitio
    """
    Contiene informacion sobre la estructura del sitio web
    """
    def __init__(self, name, url, searchUrl, resultListing, resultUrl, absoluteUrl, titleTag, bodyTag, dataTag):
        self.name = name
        self.url = url
        self.searchUrl = searchUrl #contiene al boton de busqueda
        self.resultListing = resultListing #elemento que ve en resultado todas las listas encontradas
        self.resultUrl = resultUrl #define la etiqueta donde se encuentra el link que queremos acceder
        self.absoluteUrl=absoluteUrl #creamos el valor boleano para ver si la url es absoluta o relativa,
        #absoluta = True relativa=False
        self.titleTag = titleTag #etiqueta del titulo de la noticia
        self.bodyTag = bodyTag #etiqueta del cuerpo de la noticia
        self.dataTag = dataTag #etiqueta de la fecha de publicacion de la noticia


class Crawler: #Clase que toma la URL y devuelve el objeto BeautifulSoup
    #Aqui trata las excepciones y posibles errores
    def getPage(self, url): #funcion que toma una url y devuelve un objeto BeautifulSoup
        try:
            req = requests.get(url)
        except requests.exceptions.RequestException:
            return None
        return BeautifulSoup(req.text, 'html.parser')    
    
#funcion de utilidad que nos encontrara los elementos dentro del BeautifulSoup
    def safeGet(self, pageObj, selector):
        childObj = pageObj.select(selector)
        if childObj is not None and len(childObj) > 0:
            #return childObj[0].get_text() solo entrega el primero
            return '\n'.join(
            [elem.get_text() for elem in childObj]) #entrega todos las busquedas
        return ""  #Si no pasa eso, retorna vacio o none.
    
    def search(self, topic, site): #ingresamos un tópico y el sitio
        """
        Busca en un sitio web determinado un tema determinado y registra todas las paginas 
        encontradas
        """
        bs = self.getPage(site.searchUrl + topic) #recibe la URL del sitio con el tópico
        searchResults = bs.select(site.resultListing) #definimos el objeto que contiene todos los resultados
        registrocontenido = []
        for result in searchResults: #como son varios, accedimos uno por uno
            url = result.select(site.resultUrl)[0].attrs["href"] #el atributo href contiene los links
            # Verifica si es una URL relativa o absoluta.
            if(site.absoluteUrl):
                bs = self.getPage(url) #si es absoluta
            else:
                bs = self.getPage(site.url + url) #si es relativa
            if bs is None:
                print("Tenemos un problema!!")
                return
            title = self.safeGet(bs, site.titleTag) #usamos la funcion de utilidad safeGet
            body = self.safeGet(bs, site.bodyTag)
            data = self.safeGet(bs, site.dataTag)
            if title != '' and body != '': 
                #Si titulo y cuerpo son distintos de vacios, imprimos.
                content = Content(topic, url, title, body, data)
                content.print()
                registrocontenido.append(content)
        return registrocontenido

def writeArticles(filename, articles):
    csvFile = open(filename,'wt+',encoding='utf-8')
    writer=csv.writer(csvFile)
    try:
        for article in articles:
            csvrow = [article,topic,article.title,article.data,article.body,article.url]
    finally:
        csvFile.close()
    
crawler = Crawler()
#siteData=[nombre, urlprincipal,url busqueda, etiquetaresultado,etiqueta título en lista de resultados,url absoluta,titulo de la noticia, cuerpo, fecha]
siteData = [['El ciudadano', 'https://www.elciudadano.com/', 'https://www.elciudadano.com/?s=', 'div.td_module_16 ','h3.entry-title a', True, 'h1.entry-title', 'div.td-post-content p', 'time']]


sites = []
for row in siteData:
    sites.append(Website(row[0], row[1], row[2],row[3], row[4], row[5], row[6], row[7], row[8]))

topics = ['PYTHON'] #variable de topicos que queremos extraer

articles = []
for topic in topics:
    print("GETTING INFO ABOUT: " + topic)
    for targetSite in sites: #for para recorrer los sitios
        articles.extend(crawler.search(topic, targetSite))
        crawler.search(topic, targetSite) #llamamos a la funcion search
    writeArticles('Articulos.csv', articles)

谢谢您的帮助或建议!

1 个答案:

答案 0 :(得分:0)

在将内容保存到csv的方法中,您未写入文件。代码只是打开和关闭文件指针。使用writer.writerow()

def writeArticles(filename, articles):
    csvFile = open(filename,'wt+',encoding='utf-8')
    writer=csv.writer(csvFile)
    try:
        for article in articles:
            writer.writerow([article,topic,article.title,article.data,article.body,article.url])
    finally:
        csvFile.close()