web-dev-qa-db-fra.com

Comment puis-je gratter un tableau HTML en CSV?

Le problème

J'utilise un outil au travail qui me permet de faire des requêtes et de récupérer des tableaux HTML d'informations. Je n'y ai aucun accès back-end.

Beaucoup de ces informations seraient beaucoup plus utiles si je pouvais les mettre dans une feuille de calcul pour trier, faire la moyenne, etc. Comment puis-je filtrer ces données dans un fichier CSV?

Ma première idée

Depuis que je connais jQuery, j'ai pensé que je pourrais l'utiliser pour supprimer le formatage du tableau à l'écran, insérer des virgules et des sauts de ligne, et simplement copier tout le désordre dans le bloc-notes et l'enregistrer au format CSV. De meilleures idées?

La solution

Oui, les amis, c'était aussi simple que de copier et coller. Je ne me sens pas idiot.

Plus précisément, lorsque j'ai collé dans la feuille de calcul, j'ai dû sélectionner "Collage spécial" et choisir le format "texte". Sinon, il a essayé de tout coller dans une seule cellule, même si j'ai mis en surbrillance la feuille de calcul entière.

40
Nathan Long
  • Sélectionnez le tableau HTML dans l'interface utilisateur de vos outils et copiez-le dans le presse-papiers (si c'est possible
  • Collez-le dans Excel.
  • Enregistrer en tant que fichier CSV

Cependant, il s'agit d'une solution manuelle et non automatisée.

33
mkoeller

en utilisant python:

par exemple, imaginez que vous voulez gratter les citations de forex sous forme csv à partir d'un site comme: fxquotes

ensuite...

from BeautifulSoup import BeautifulSoup
import urllib,string,csv,sys,os
from string import replace

date_s = '&date1=01/01/08'
date_f = '&date=11/10/08'
fx_url = 'http://www.oanda.com/convert/fxhistory?date_fmt=us'
fx_url_end = '&lang=en&margin_fixed=0&format=CSV&redirected=1'
cur1,cur2 = 'USD','AUD'
fx_url = fx_url + date_f + date_s + '&exch=' + cur1 +'&exch2=' + cur1
fx_url = fx_url +'&expr=' + cur2 +  '&expr2=' + cur2 + fx_url_end
data = urllib.urlopen(fx_url).read()
soup = BeautifulSoup(data)
data = str(soup.findAll('pre', limit=1))
data = replace(data,'[<pre>','')
data = replace(data,'</pre>]','')
file_location = '/Users/location_edit_this'
file_name = file_location + 'usd_aus.csv'
file = open(file_name,"w")
file.write(data)
file.close()

edit: pour obtenir les valeurs d'une table: exemple de: palewire

from mechanize import Browser
from BeautifulSoup import BeautifulSoup

mech = Browser()

url = "http://www.palewire.com/scrape/albums/2007.html"
page = mech.open(url)

html = page.read()
soup = BeautifulSoup(html)

table = soup.find("table", border=1)

for row in table.findAll('tr')[1:]:
    col = row.findAll('td')

    rank = col[0].string
    artist = col[1].string
    album = col[2].string
    cover_link = col[3].img['src']

    record = (rank, artist, album, cover_link)
    print "|".join(record)
12
Thorvaldur

Ceci est ma version python utilisant la dernière version (actuellement) de BeautifulSoup qui peut être obtenue en utilisant, par exemple,

$ Sudo easy_install beautifulsoup4

Le script lit HTML à partir de l'entrée standard et génère le texte trouvé dans tous les tableaux au format CSV approprié.

#!/usr/bin/python
from bs4 import BeautifulSoup
import sys
import re
import csv

def cell_text(cell):
    return " ".join(cell.stripped_strings)

soup = BeautifulSoup(sys.stdin.read())
output = csv.writer(sys.stdout)

for table in soup.find_all('table'):
    for row in table.find_all('tr'):
        col = map(cell_text, row.find_all(re.compile('t[dh]')))
        output.writerow(col)
    output.writerow([])
10
Juan A. Navarro

Encore plus facile (car il vous l'enregistre pour la prochaine fois) ...

Dans Excel

Données/Importer des données externes/Nouvelle requête Web

vous amènera à une invite d'URL. Entrez votre URL et elle délimitera les tableaux disponibles sur la page à importer. Voila.

5
dkretz

Deux façons me viennent à l'esprit (en particulier pour ceux d'entre nous qui n'ont pas Excel):

  • Google Spreadsheets a ne excellente fonction importHTML :
    • =importHTML("http://example.com/page/with/table", "table", index
    • L'index commence à 1
    • Je recommande un copy et paste values peu de temps après l'importation
    • Fichier -> Télécharger en tant que -> CSV
  • La superbe bibliothèque Pandas de Python a à portée de main read_html et to_csv fonctions
4
n8henrie

Rapide et sale:

Copiez du navigateur dans Excel, enregistrez-le au format CSV.

Meilleure solution (pour une utilisation à long terme):

Écrivez un peu de code dans la langue de votre choix qui réduira le contenu html et supprimez les bits que vous souhaitez. Vous pourriez probablement lancer toutes les opérations de données (tri, moyenne, etc.) en plus de la récupération des données. De cette façon, vous n'avez qu'à exécuter votre code et vous obtenez le rapport réel que vous souhaitez.

Tout dépend de la fréquence à laquelle vous effectuerez cette tâche particulière.

2
James Van Huis

Basic Python utilisant BeautifulSoup, prenant également en compte les lignes rowpan et colspan:

from BeautifulSoup import BeautifulSoup

def table2csv(html_txt):
   csvs = []
   soup = BeautifulSoup(html_txt)
   tables = soup.findAll('table')

   for table in tables:
       csv = ''
       rows = table.findAll('tr')
       row_spans = []
       do_ident = False

       for tr in rows:
           cols = tr.findAll(['th','td'])

           for cell in cols:
               colspan = int(cell.get('colspan',1))
               rowspan = int(cell.get('rowspan',1))

               if do_ident:
                   do_ident = False
                   csv += ','*(len(row_spans))

               if rowspan > 1: row_spans.append(rowspan)

               csv += '"{text}"'.format(text=cell.text) + ','*(colspan)

           if row_spans:
               for i in xrange(len(row_spans)-1,-1,-1):
                   row_spans[i] -= 1
                   if row_spans[i] < 1: row_spans.pop()

           do_ident = True if row_spans else False

           csv += '\n'

       csvs.append(csv)
       #print csv

   return '\n\n'.join(csvs)
2
Aviad

Excel peut ouvrir une page http.

Par exemple:

  1. Cliquez sur Fichier, Ouvrir

  2. Sous nom de fichier, collez l'URL, c'est-à-dire: Comment puis-je gratter un tableau HTML en CSV?

  3. Cliquez sur OK

Excel fait de son mieux pour convertir le code HTML en tableau.

Ce n'est pas la solution la plus élégante, mais ça marche!

2
Christian Payne

Voici un exemple testé qui combine grequest et soupe pour télécharger de grandes quantités de pages à partir d'un site Web structuré:

#!/usr/bin/python

from bs4 import BeautifulSoup
import sys
import re
import csv
import grequests
import time

def cell_text(cell):
    return " ".join(cell.stripped_strings)

def parse_table(body_html):
    soup = BeautifulSoup(body_html)
    for table in soup.find_all('table'):
        for row in table.find_all('tr'):
            col = map(cell_text, row.find_all(re.compile('t[dh]')))
            print(col)

def process_a_page(response, *args, **kwargs): 
    parse_table(response.content)

def download_a_chunk(k):
    chunk_size = 10 #number of html pages
    x = "http://www.blahblah....com/inclusiones.php?p="
    x2 = "&name=..."
    URLS = [x+str(i)+x2 for i in range(k*chunk_size, k*(chunk_size+1)) ]
    reqs = [grequests.get(url, hooks={'response': process_a_page}) for url in URLS]
    resp = grequests.map(reqs, size=10)

# download slowly so the server does not block you
for k in range(0,500):
    print("downloading chunk ",str(k))
    download_a_chunk(k)
    time.sleep(11)
1
user1205101

Avez-vous essayé de l'ouvrir avec Excel? Si vous enregistrez une feuille de calcul dans Excel au format html, vous verrez le format qu'Excel utilise. À partir d'une application Web que j'ai écrite, j'ai craché ce format html afin que l'utilisateur puisse exporter vers Excel.

0
Will Rickards

Si vous effectuez un grattage d'écran et que la table que vous essayez de convertir a un ID donné, vous pouvez toujours effectuer une analyse regex du code HTML avec des scripts pour générer un CSV.

0
andy