Screen scraping 如何将HTML表格刮到CSV? 问题

Screen scraping 如何将HTML表格刮到CSV? 问题,screen-scraping,Screen Scraping,我在工作中使用了一个工具,它可以让我进行查询并获取HTML信息表。我没有任何后端访问权限 如果我可以将这些信息放入电子表格中进行排序、平均等,那么这些信息中的许多信息将更加有用。如何将这些数据筛选到CSV文件中? 我的第一个想法 因为我了解jQuery,所以我想我可以用它去掉屏幕上的表格格式,插入逗号和换行符,然后将整个混乱复制到记事本中并保存为CSV还有更好的主意吗? 解决方案 是的,伙计们,这真的像复制和粘贴一样简单。我不觉得自己很傻吗 具体来说,当我粘贴到电子表格中时,我必须选择“粘贴特殊

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

如果我可以将这些信息放入电子表格中进行排序、平均等,那么这些信息中的许多信息将更加有用。如何将这些数据筛选到CSV文件中?

我的第一个想法 因为我了解jQuery,所以我想我可以用它去掉屏幕上的表格格式,插入逗号和换行符,然后将整个混乱复制到记事本中并保存为CSV还有更好的主意吗?

解决方案 是的,伙计们,这真的像复制和粘贴一样简单。我不觉得自己很傻吗

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

  • 在工具的UI中选择HTML表并将其复制到剪贴板(如果可能的话)
  • 将其粘贴到Excel中
  • 另存为CSV文件
但是,这是一个手动解决方案,而不是自动解决方案。

快速且肮脏:

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

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

用您选择的语言编写一段代码,将html内容拉下来,并提取出您想要的内容。您可能会在数据检索的基础上加入所有的数据操作(排序、平均等)。这样,您只需运行代码,就可以得到您想要的实际报告


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

您是否尝试过使用excel打开它? 如果在excel中将电子表格保存为html,您将看到excel使用的格式。
从我编写的一个web应用程序中,我吐出了这种html格式,这样用户就可以导出到excel。

如果您正在抓屏,并且您试图转换的表有一个给定的ID,您可以随时对html进行正则表达式解析,并编写一些脚本来生成CSV。

使用python:

例如,假设您想从某个网站上以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()

Excel可以打开http页面

例如:

  • 单击文件,打开

  • 在“文件名”下,粘贴URL,即:

  • 单击“确定”

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

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

    甚至更简单(因为它可以为您保存它以备下次使用)

    在Excel中

    数据/导入外部数据/新建Web查询


    将带您进入一个url提示符。输入您的url,它将在页面上划界要导入的可用表。瞧。

    这是我的python版本,使用(当前)最新版本的BeautifulSoup,可通过以下方式获得:

    #!/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([])
    
    该脚本从标准输入读取HTML,并以正确的CSV格式输出所有表中的文本

    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)
    
    我想到了两种方法(特别是对于我们这些没有Excel的人):

    • 谷歌电子表格有:
      • =importHTML(“http://example.com/page/with/table“,”表格“,索引
      • 索引从1开始
      • 我建议在导入后不久进行
        复制
        粘贴值
      • 文件->下载为->CSV
    • Python一流的库具有便捷的功能
      • 下面是提示输入URL、URL中的哪个表以及CSV的文件名

    使用BeautifulSoup的基本Python实现,同时考虑rowspan和colspan:

    #!/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)
    
    从美化组导入美化组
    def表格2CSV(html_txt):
    csvs=[]
    soup=BeautifulSoup(html\U txt)
    tables=soup.findAll('table')
    对于表中的表:
    csv=“”
    行=table.findAll('tr')
    行跨度=[]
    do_ident=False
    对于行中的tr:
    cols=tr.findAll(['th','td'])
    对于cols中的单元格:
    colspan=int(cell.get('colspan',1))
    rowspan=int(cell.get('rowspan',1))
    如果不确定:
    do_ident=False
    csv+=','*(列(行跨度))
    如果行span>1:行_span.append(行span)
    csv+='{text}'.格式(text=cell.text)+','*(colspan)
    如果行_跨越:
    对于X范围内的i(len(row_跨度)-1,-1,-1):
    第u行跨距[i]=1
    如果行_跨越[i]<1:row_跨越.pop()
    如果行跨越其他项,则do_ident=True
    csv+='\n'
    csvs.append(csv)
    #打印csv
    返回'\n\n'。加入(CSV)
    
    下面是一个经过测试的示例,它结合了grequest和soup从结构化网站下载大量页面:


    这适用于IE,但我不相信它适用于FF,即使是Paste Special,我相信它只是将所有内容转储到第一个单元格中。不,我是用FF3完成的。在执行Paste Special>文本之前,我在电子表格中选择了all。如果基础HTML以某种方式格式化,可能它不起作用?我认为此解决方案不具有可伸缩性。Fro我的问题是,Nathan似乎想要下面给出的代码。有没有一种简单的方法可以使用Beauty soup将html表解析为csv?您的示例似乎侧重于包含在“pre”标记中的文本。使用Beauty soup,您只需查找任何您喜欢的标记,这些标记靠近您想要的数据,然后findAll('thattag',limit x)…另外,只要看看Beautiful soup的文档,有许多选项可以完成各种任务。很好!我尝试在这里概括您的解决方案:任何如何改进数据的链接?我为一个html行获得多个excel行(一个TD有注释、alt文本等。这将成为excel中的多行)我最终使用了jQuery的想法,因为我想要XML,而在Excel中映射XML是一件非常麻烦的事情(对于临时数据集)…事实证明,对于任何使用JS控制台的网站来说,这都是非常容易的事情(如果不使用jQuery.JS,则动态注入jQuery.JS)
    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)
    
    #!/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)