【问题标题】:How can I scrape an HTML table to CSV?如何将 HTML 表格抓取到 CSV?
【发布时间】:2023-03-25 13:50:01
【问题描述】:

问题

我在工作中使用了一个工具,它可以让我进行查询并获取 HTML 信息表。我没有任何形式的后端访问权限。

如果我可以将这些信息放入电子表格中进行排序、平均等操作,这些信息会更加有用。如何将这些数据截屏到 CSV 文件中? p>

我的第一个想法

因为我知道 jQuery,我想我可以用它来去除屏幕上的表格格式,插入逗号和换行符,然后将整个混乱复制到记事本中并保存为 CSV。 有更好的想法吗?

解决方案

是的,伙计们,这真的就像复制和粘贴一样简单。我不觉得很傻吗。

具体来说,当我粘贴到电子表格中时,我必须选择“选择性粘贴”并选择“文本”格式。否则它会尝试将所有内容粘贴到单个单元格中,即使我突出显示了整个电子表格。

【问题讨论】:

  • 我最终使用了 jQuery 想法,因为我想要 XML,并且在 Excel 中映射 XML 是一件非常痛苦的事情(对于临时数据集)。事实证明这对于 来说很容易做到使用 JS 控制台的任何 网站(如果没有,则动态注入 jquery.js,然后使用从 HTML 表数据到 csv/xml/json/whatever 的简单转换使用$("tr", "#table tbody").each()

标签: screen-scraping


【解决方案1】:
  • 在工具的 UI 中选择 HTML 表格并将其复制到剪贴板(如果可能的话
  • 将其粘贴到 Excel 中。
  • 另存为 CSV 文件

但是,这是一种手动解决方案,而不是自动解决方案。

【讨论】:

  • 这适用于 IE,但我不相信它适用于 FF,即使使用特殊粘贴,我相信它只是将所有内容转储到第一个单元格中。
  • 不,我是用 FF3 做的。在执行选择性粘贴 > 文本之前,我在电子表格中选择了所有内容。如果底层的 HTML 以某种方式格式化,也许它不起作用?
  • 我不认为这个解决方案是可扩展的。从这个问题来看,内森似乎想要一个像下面给出的代码。
【解决方案2】:

这是一个经过测试的示例,它结合了 grequest 和 soup 从结构化网站下载大量页面:

#!/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)

【讨论】:

    【解决方案3】:

    使用 BeautifulSoup 的基本 Python 实现,同时考虑 rowspan 和 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)
    

    【讨论】:

      【解决方案4】:

      我想到了两种方法(尤其是对于我们这些没有 Excel 的人):

      • Google 电子表格有 an excellent importHTML function
        • =importHTML("http://example.com/page/with/table", "table", index
        • 索引从 1 开始
        • 我推荐在导入后不久使用copypaste values
        • 文件 -> 下载为 -> CSV
      • Python 出色的Pandas 库具有方便的read_htmlto_csv 函数

      【讨论】:

      • 这是一个很好的提示,谢谢!
      【解决方案5】:

      这是我使用(当前)最新版本的 BeautifulSoup 的 python 版本,可以使用,例如,

      $ sudo easy_install beautifulsoup4
      

      脚本从标准输入读取 HTML,并以正确的 CSV 格式输出在所有表格中找到的文本。

      #!/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([])
      

      【讨论】:

      • 有效!由于我正在使用 unicode 字符,因此将 import csv 更改为 import unicodecsv as csv 以下:stackoverflow.com/a/31642070/4355695。必须安装 unicodecsv :pip2 install unicodecsv
      【解决方案6】:

      使用python:

      例如,假设您想从某个网站(例如:fxquotes)以 csv 格式抓取外汇报价

      那么……

      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()
      

      编辑:从表中获取值: 示例来自: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)
      

      【讨论】:

      • 有没有一种简单的方法可以使用漂亮的汤将 html 表格解析为 csv?您的示例似乎侧重于包含在“pre”标签中的文本。
      • 用漂亮的汤,你只需寻找任何你喜欢的标签,它靠近你想要的数据,然后 findAll('thattag',limit=x) ...
      • 另外,看看Beautiful soup的文档,有很多选项可以完成各种任务。
      • 不错!我试图在这里概括您的解决方案:stackoverflow.com/questions/2611418/scrape-html-tables
      【解决方案7】:

      更简单(因为它会为您保存下次使用)...

      在 Excel 中

      数据/导入外部数据/新建网页查询

      将带您进入 url 提示符。输入您的网址,它将在页面上分隔要导入的可用表。瞧。

      【讨论】:

      • 任何链接如何改进数据?我为一个 html 行获得多个 excel 行(一个 TD 有 cmets、alt-text 等。这变成了 excel 中的多行)
      【解决方案8】:

      Excel 可以打开 http 页面。

      例如:

      1. 点击文件,打开

      2. 在文件名下,粘贴 URL 即:How can I scrape an HTML table to CSV?

      3. 点击确定

      Excel 尽最大努力将 html 转换为表格。

      它不是最优雅的解决方案,但确实有效!

      【讨论】:

        【解决方案9】:

        如果您正在抓取屏幕并且您尝试转换的表格具有给定的 ID,您始终可以对 html 进行正则表达式解析以及一些脚本以生成 CSV。

        【讨论】:

          【解决方案10】:

          你试过用excel打开吗? 如果您将 excel 中的电子表格另存为 html,您将看到 excel 使用的格式。 从我编写的一个网络应用程序中,我吐出了这种 html 格式,以便用户可以导出到 excel。

          【讨论】:

            【解决方案11】:

            又快又脏:

            从浏览器复制到 Excel,另存为 CSV。

            更好的解决方案(长期使用):

            用您选择的语言编写一些代码,将 html 内容拉下来,并刮出您想要的部分。您可能会在数据检索之上投入所有数据操作(排序、平均等)。这样,您只需运行代码即可获得所需的实际报告。

            这完全取决于您执行此特定任务的频率。

            【讨论】:

              猜你喜欢
              • 2011-02-06
              • 1970-01-01
              • 1970-01-01
              • 2018-02-24
              • 2016-05-24
              • 2010-10-29
              • 2020-05-04
              • 2020-11-08
              • 2014-02-08
              相关资源
              最近更新 更多