如何在BeautifulSoup中使用Python将这些由单行中的多列分隔的数据导出到.csv或.xls中?

2024-05-22 17:52:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我当前将此数据存储为result变量。你知道吗

['Draw Date:']
['Draw Date:']
['']
['']
['']
['Draw Date:  2019-01-15']
['']
['Perdana Lottery']
[]
['F', '2771', 'M', '0133', 'A', '6215']
[]
['A', '----', 'B', '1859', 'C', '3006', 'D', '3327']
['E', '5699', 'F', '----', 'G', '1123', 'H', '9193']
['I', '9076', 'J', '0573', 'K', '0950', 'L', '7258']
['', 'M', '-----', '', '', '']
['N', '1226', 'O', '0565', 'P', '1563', 'Q', '1420']
['R', '5265', 'S', '9345', 'T', '0483', 'U', '0933']
['', 'V', '6468', 'W', '3247', '']
['']
['']
['']
['']

我想将此数据导出到.csv或.xls格式的表中,如下所示:

+------------+----------+----------+----------+----------+-------------+
| Date       | First    | Second   | Third    | Special  | Consolation |
+------------+---+------+---+------+---+------+---+------+---+---------+
| 2019-01-15 | F | 2771 | M | 0133 | A | 6215 | A | ---- | N | 1226    |
|            |   |      |   |      |   |      | B | 1859 | O | 0565    |
|            |   |      |   |      |   |      | C | 3006 | P | 1563    |
|            |   |      |   |      |   |      | ... etc  | ... etc     |
+------------+---+------+---+------+---+------+----------+-------------+

。。。etc表示上述结果变量的剩余数据。我不是为了避免混乱才写出来的。你知道吗

那么,我应该使用哪些模块以及如何使用它们呢?请注意,我是个十足的Python新手。我只知道一些PHP的东西,但老实说,我开始喜欢py了。你知道吗


Tags: csv数据date格式etcresultxlsfirst
1条回答
网友
1楼 · 发布于 2024-05-22 17:52:22

第一个问题是你需要知道奖品之间的分配。如果看不到Special Prize文本,这将很困难。另一种方法是使用find_all()来发现tdth元素。列表仅添加非空单元格。这将产生一个包含您需要的所有数据的列表。你知道吗

cols包含所需列的列表。这是手动填写的第一,第二和第三奖,因为这些条目应该是固定的。然后使用循环将相应的字母和奖品添加到最后四列。你知道吗

Python groupby()函数可用于将列表分组到由split_on中的元素分隔的子组中。你知道吗

from itertools import groupby, zip_longest, islice
from bs4 import BeautifulSoup
import requests
import csv


def grouper(iterable, n):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x')  > ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip(*args)


response = requests.get("http://perdana4d.com/resulten.php")
soup = BeautifulSoup(response.content, 'lxml') 
rows = [cell.get_text(strip=True) for cell in soup.find_all(['td', 'th']) if len(cell.get_text(strip=True))]
draw_date = rows[2].split(' ')[-1]
split_on = ['Special Prize', 'Consolation Prize']

cols = [
    ['Date', draw_date], 
    ['FirstL', rows[7]], 
    ['FirstP', rows[8]], 
    ['SecondL', rows[9]], 
    ['SecondP', rows[10]], 
    ['ThirdL', rows[11]], 
    ['ThirdP', rows[12]], 
    ['SpecialL'], 
    ['SpecialP'], 
    ['ConsolationL'], 
    ['ConsolationP']
    ]

col_l = islice(cols, 7, None, 2)
col_p = islice(cols, 8, None, 2)

for k, g in groupby(rows[13:], lambda x: x not in split_on):
    if k:
        l = next(col_l)
        p = next(col_p)

        for letter, prize in grouper(g, 2):
            l.append(letter)
            p.append(prize)

with open('output.csv', 'w', newline='') as f_output:
    csv.writer(f_output).writerows(zip_longest(*cols, fillvalue=''))

这将导致CSV文件在加载到电子表格包时具有以下类型的格式:

CSV format

这里使用了很多Python技术,需要花一段时间才能理解。grouper例如是itertools recipes之一。islice()是一种迭代对象的方法,无需从第一个位置开始。你知道吗

CSV文件的最终输出是使用Python的CSV库完成的。这会将行列表转换为格式正确的输出行。由于数据是列格式的,因此需要一种技巧将列表转换为行列表,这是使用zip_longest()完成的。你知道吗

如果您向代码中添加print语句以查看数据的外观,可能会有所帮助。你知道吗

注意,要将数据直接保存为Excel格式(.xlsx),您需要安装另一个库,例如可以使用openpyxlxlwt。你知道吗

相关问题 更多 >

    热门问题