【问题标题】:Python download table and save to ExcelPython下载表并保存到Excel
【发布时间】:2016-12-22 13:56:52
【问题描述】:

我正在尝试从 html 下载一个表格,该表格不是通常的 td/tr 格式并包含图像并将结果保存到 excel。

html 代码如下所示:

<div class="dynamicBottom">
<div class="dynamicLeft">
<div class="content_block details_block scroll_tabs" data-tab="TABS_DETAILS">
<div class="header_with_improve wrap">
<a href="/UpdateListing.html" onclick="ta.setEvtCookie('UpdateListing', 'entry-detail-moreinfo', null, 0, '/UpdateListingRedesign')"><div class="improve_listing_btn ui_button primary small">improve this entry</div></a>
<h3 class="tabs_header">Details</h3> </div>
<div class="details_tab">
<div class="table_section">
<div class="row">
<div class="ratingSummary wrap">
<div class="histogramCommon bubbleHistogram wrap">
<div class="colTitle">
Rating
</div>
<ul class="barChart">
<li>
<div class="ratingRow wrap">
<div class="label part ">
<span class="text">Location</span>
</div>
<div class="wrap row part ">
<span class="rate sprite-rating_s rating_s"> <img class="sprite-rating_s_fill rating_s_fill s45" src="https://static.tacdn.com/img2/x.gif" alt="45 out of fifty points">
</span>
</div>
</div>
<div class="ratingRow wrap">
<div class="label part ">
<span class="text">Service</span>
</div>
<div class="wrap row part ">
<span class="rate sprite-rating_s rating_s"> <img class="sprite-rating_s_fill rating_s_fill s45" src="https://static.tacdn.com/img2/x.gif" alt="45 out of fifty points">
</span>
</div>
</div>
</li>

我想得到这张桌子:[位置 45 分,满分 50 分,服务 45 分,满分 50 分]。并将结果保存到 Excel 文件中。 Excel 文件中的列标题应说明“位置”和“45”或“50 分中的 45”下方的单元格。下一个列标题应显示“服务”,下面行中的单元格应显示“45”或“50 分中的 45”。我设法保存了位置的名称和评级,但服务评级的单元格仍然为空。

我的 python 代码如下所示:

workbook = xlsxwriter.Workbook('File.xlsx')
worksheet = workbook.add_worksheet()
row=1
col=0 
for url in urls: 
    r=requests.get(url)
    soup=BeautifulSoup(r.content, "lxml")

    worksheet.write('A1', 'name')
    worksheet.write('B1', 'location')
    worksheet.write('C1', 'service')

    row += 1
    name= soup.find_all("div", {"class": "LocationName"}) 
    for item in name:
        worksheet.write_string(row, col, item.text)
    for div in soup.find_all('div', class_="ratingRow wrap"):
        text = div.text.strip()
        alt = div.find('img').get('alt')
        print(text, alt)
        worksheet.write_string(row, col+1, alt)

打印功能给出

Location 45 out of fifty points
Service 45 out of fifty points

控制台打印位置和服务的所有结果,但在 Excel 工作表中仅显示位置评级,而服务评级的单元格保持为空。我尝试了 enumerate 函数,但是在 Excel 的一行中的每个单元格中只有一个位置评级字符,但也没有出现服务评级结果。

0 4
1 5
2 
3 o 
4 u
5 t
6 
7 o 
8 f
9 
10 f
11 i
12 f
13 t
14 y
15 
16 p
17 o
18 i
19 n
19 t
20 s

有什么方法可以告诉 Python 将打印文本“50 分中的 45 分”中的第二行保存到 Excel 中“服务”下方的单元格中?我彻底搜索但找不到解决方案。非常感谢您的帮助!

【问题讨论】:

    标签: excel python-3.x beautifulsoup xlsxwriter


    【解决方案1】:

    我不明白为什么您有 2 个单独的循环,而且我找不到类 LocationName 在 HTML 中的任何位置出现的位置。因为我希望您不会为此获得任何结果,所以我希望在第一个循环中不会写任何内容 - 与您报告的内容一致。似乎您应该在第二个循环中将 text 写入 (row, col)。

    根据讨论,第一个循环使用 HTML 中其他数据的名称,每页仅出现一次。

    我的建议是避免可能覆盖 (row, col+1) 单元格:

    workbook = xlsxwriter.Workbook('File.xlsx')
    worksheet = workbook.add_worksheet()
    row=1
    for url in urls: 
        col=0
        r=requests.get(url)
        soup=BeautifulSoup(r.content, "lxml")
    
        worksheet.write('A1', 'name')
        worksheet.write('B1', 'location')
        worksheet.write('C1', 'service')
    
        row += 1
        name= soup.find_all("div", {"class": "LocationName"}) 
        for item in name:
            worksheet.write_string(row, col, item.text)
        for div in soup.find_all('div', class_="ratingRow wrap"):
            col+=1
            text = div.text.strip()
            alt = div.find('img').get('alt')
            print(text, alt)
            worksheet.write_string(row, col, alt)
    

    【讨论】:

    • 对不起,我在html代码中忘记了这一行&lt;div class="LocationName"&gt;Hotel Beispiel&lt;/div&gt;
    • 对不起,我在 html 代码&lt;div class="LocationName"&gt;Hotel Beispiel&lt;/div&gt; 中忘记了这一行,名称实际上是打印到 Excel 文件中的。它只是将服务评级的单元格留空。有什么办法可以做到吗?也许通过使用数据框?
    • 好的(我想我应该把它作为评论留下),所以你有每家酒店的位置和服务,你只对将这些替代文本放入 Excel 工作表感兴趣。在我看来,您的问题与 xlsxwriter 完全隔离,因为您可以打印要写入它的字符串。我可以轻松地将字符串写入多个单元格,并尝试自己复制它。您可能正在做的另一件事是在第二个循环中覆盖 (row, col+1),我会尝试在那里迭代您的 col 值作为调试方法。
    • 我这样说是因为我最好的猜测是soup.find_all('div', class_="ratingRow wrap") 迭代器中的最后一项为alt 提供了一个空字符串,它替换了您之前写入单元格的内容。
    • 谢谢,艾伦!我将如何迭代 col 值以将其用作调试方法?我不知道该怎么做。你是对的,我可以手动将字符串写入单元格,但我想为 15,000 个 URL 执行此操作,这将是时间效率低下的。如果使用 csv 文件更容易解决问题,我也可以使用 csv 文件。
    猜你喜欢
    • 1970-01-01
    • 2021-01-07
    • 2019-10-31
    • 2020-12-17
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多