Как мне получить таблицу и поставить ее в Excel без длинного кода - PullRequest
2 голосов
/ 02 мая 2020

У меня есть лист Google с данными о коронавирусе. Я хочу обновить его с помощью сайта Worldometer. Я не хочу копировать селектор CSS для каждой тысячи ячеек в моем коде.

Я попытался получить таблицу, но после каждого она разделяется символом новой строки. Я получил таблицу со следующим кодом

    import bs4
    import requests

    res = requests.get('https://www.worldometers.info/coronavirus')
    soup = bs4.BeautifulSoup(res.text, 'html.parser')
    print(len(soup.select('table')))
    txt = soup.select('table')[1]
    print(txt.text)

Есть ли способ сделать то, что мы получаем из таблицы int, форматом, который можно преобразовать в Excel или превратить саму таблицу HTML в Excel, чтобы будет отформатирован правильно.

Ответы [ 2 ]

2 голосов
/ 02 мая 2020

Я предлагаю вам взглянуть на следующие python модули:

  1. pandas: для обработки табличных данных ( официальная документация , руководство по преобразованию таблицы HTML в excel );
  2. openpyxl : для таблиц Excel (см. это руководство );
  3. EZSheets ; для таблиц Google (см. это руководство ).

Я надеюсь, что эти ресурсы помогут вам.

Редактировать: приведенный ниже код (на основе this ) должен позволить вам получить таблицу.

import pandas as pd, openpyxl, os.path

if os.path.isfile("coronaData.xlsx") == False:
    openpyxl.Workbook().save("coronaData.xlsx")

url = "https://www.worldometers.info/coronavirus"
hdr = {
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36",
    "X-Requested-With": "XMLHttpRequest"
    }

#See https://stackoverflow.com/questions/45943179/python-pandas-typeerror-first-argument-must-be-string-or-compiled-pattern#45944194
key = str(frozenset(hdr.items())) 

table = pd.read_html(url, key)[0] 

table.to_excel("coronaData.xlsx") 


Однако я все еще спотыкаюсь об ошибке urllib.error.HTTPError: HTTP Error 403: Forbidden , который, вероятно, может быть решен с правильными заголовками (hdr). Возможно, было бы проще с другим сайтом (без hdr и ключевых переменных, например Wikipedia ).

0 голосов
/ 12 мая 2020

Я думаю, что нашел ответ на свой вопрос. Я провел некоторое исследование и нашел, как превратить его в файл CSV, добавив каждую строку. Я также могу взять население, используя этот метод. После того, как я получил CSV-файл, я просто поместил его на свой диск Google и преобразовал в лист Google. Код показан ниже.

    import bs4
    import requests
    import csv

    res = requests.get('https://www.worldometers.info/coronavirus')
    soup = bs4.BeautifulSoup(res.text, 'html.parser')
    print(len(soup.select('table')))
    txt = soup.select('table')[1]
    txt2 = bs4.BeautifulSoup(requests.get('https://www.worldometers.info/world- 
    population/population-by-country/').text,
                     'html.parser').select('table')[0]
    output_covidrows = []
    output_populatoinrows = []

    for table_row2 in txt2.findAll('tr'):
    columns2 = table_row2.findAll('td')
    output_row2 = []
    for column2 in columns2:
    output_row2.append(column2.text.strip())
    output_populatoinrows.append(output_row2)

    for table_row in txt.findAll('tr'):
    columns = table_row.findAll('td')
    output_row = []
    for column in columns:
         output_row.append(column.text.strip())
         for populationentry in output_populatoinrows:
             if len(populationentry) < 2 or len(output_row) < 2:
                 continue
             if populationentry[1] == output_row[0]:
                  output_row.append(populationentry[2])
                  output_row.append(populationentry[9])
         if len(output_row) > 2:
               output_covidrows.append(output_row)
    with open('output.csv', 'w') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(
            ['Country', 'Total Cases', 'New Cases', 'Total Deaths', 'New Deaths', 
             'Total Recovered', 'Active Cases',
              'Serious Cases', 'Tot Cases per 1m', 'Deaths per 1m', 'Total tests', 
             'Tests per 1m', 'Region', 'Population',
              'Med Age'])
         writer.writerows(output_covidrows)

    print('Done')
...