【问题标题】:Python: Get html table data by xpathPython:通过xpath获取html表格数据
【发布时间】:2015-04-03 01:00:56
【问题描述】:

我觉得从 html 表中提取数据非常困难,需要为每个站点自定义构建。我非常希望在这里被证明是错误的。。

是否有一种简单的 Pythonic 方法可以通过使用感兴趣表的 url 和 xpath 从网站中提取字符串和数字?

例子:

url_str = 'http://www.fdmbenzinpriser.dk/searchprices/5/'
xpath_str = //*[@id="sortabletable"]

我曾经有一个可以从该站点获取数据的脚本。却丢了。我记得我正在使用标签 '' 和一些字符串逻辑.. 不是很漂亮

我知道像thingspeak 这样的网站可以做这些事情..

【问题讨论】:

    标签: python html python-2.7 parsing xpath


    【解决方案1】:

    有一个相当通用的模式可以用来解析很多,但不是 全部,表格。

    import lxml.html as LH
    import requests
    import pandas as pd
    def text(elt):
        return elt.text_content().replace(u'\xa0', u' ')
    
    url = 'http://www.fdmbenzinpriser.dk/searchprices/5/'
    r = requests.get(url)
    root = LH.fromstring(r.content)
    
    for table in root.xpath('//table[@id="sortabletable"]'):
        header = [text(th) for th in table.xpath('//th')]        # 1
        data = [[text(td) for td in tr.xpath('td')]  
                for tr in table.xpath('//tr')]                   # 2
        data = [row for row in data if len(row)==len(header)]    # 3 
        data = pd.DataFrame(data, columns=header)                # 4
        print(data)
    
    1. 您可以使用table.xpath('//th') 查找列名。
    2. table.xpath('//tr') 返回行,对于每一行,tr.xpath('td') 返回代表表格一个“单元格”的元素。
    3. 有时您可能需要过滤掉某些行,例如在本例中,行 值少于标头。
    4. 如何处理数据(列表列表)由您决定。这里我只使用 Pandas 进行演示:

            Pris                               Adresse       Tidspunkt
    0       8.04           Brovejen 18 5500 Middelfart   3 min 38 sek 
    1       7.88         Hovedvejen 11 5500 Middelfart   4 min 52 sek 
    2       7.88         Assensvej 105 5500 Middelfart   5 min 56 sek 
    3       8.23    Ejby Industrivej 111 2600 Glostrup   6 min 28 sek 
    4       8.15            Park Alle 125 2605 Brøndby  25 min 21 sek 
    5       8.09           Sletvej 36 8310 Tranbjerg J  25 min 34 sek 
    6       8.24      Vindinggård Center 29 7100 Vejle   27 min 6 sek 
    7     7.99 *         Søndergade 116 8620 Kjellerup  31 min 27 sek 
    8     7.99 *   Gertrud Rasks Vej 1 9210 Aalborg SØ  31 min 27 sek 
    9     7.99 *              Sorøvej 13 4200 Slagelse  31 min 27 sek 
    

    【讨论】:

    • 非常有用的模式,但很好奇如何使用常规模式从表格行中提取 href 链接?
    • @TimothyLombard:在text 函数中,您可能会使用elt.xpath('//a/@href') 之类的东西,而不是elt.text_content()....,具体取决于HTML。如需更具体的帮助,最好发布一个新问题,其中包含您正在处理的 HTML 示例和所需的输出。
    • 不错的代码。如果有两个标题,而顶部的标题有一个行跨度怎么办?
    【解决方案2】:

    如果你的意思是所有的文字:

    from bs4 import BeautifulSoup
    
    url_str = 'http://www.fdmbenzinpriser.dk/searchprices/5/'
    import requests
    
    r = requests.get(url_str).content
    
    print([x.text for x in BeautifulSoup(r).find_all("table",attrs={"id":"sortabletable"})]
    
    ['Pris\nAdresse\nTidspunkt\n\n\n\n\n* Denne pris er indberettet af selskabet Indberet pris\n\n\n\n\n\n\xa08.24\n\xa0Gladsaxe Møllevej 33 2860 Søborg\n7 min 4 sek \n\n\n\n\xa08.89\n\xa0Frederikssundsvej 356 2700 Brønshøj\n9 min 10 sek \n\n\n\n\xa07.98\n\xa0Gartnerivej 1 7500 Holstebro\n14 min 25 sek \n\n\n\n\xa07.99 *\n\xa0Søndergade 116 8620 Kjellerup\n15 min 7 sek \n\n\n\n\xa07.99 *\n\xa0Gertrud Rasks Vej 1 9210 Aalborg SØ\n15 min 7 sek \n\n\n\n\xa07.99 *\n\xa0Sorøvej 13 4200 Slagelse\n15 min 7 sek \n\n\n\n\xa08.08 *\n\xa0Tørholmsvej 95 9800 Hjørring\n15 min 7 sek \n\n\n\n\xa08.09 *\n\xa0Nordvej 6 9900 Frederikshavn\n15 min 7 sek \n\n\n\n\xa08.09 *\n\xa0Skelmosevej  89 6980 Tim\n15 min 7 sek \n\n\n\n\xa08.09 *\n\xa0Højgårdsvej 2 4000 Roskilde\n15 min 7 sek']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-19
      • 2016-05-29
      • 2023-03-17
      • 1970-01-01
      • 2014-11-28
      • 2018-08-27
      • 2021-04-26
      • 1970-01-01
      相关资源
      最近更新 更多