如何使用BeautifulSoup中的Python将单行中多列分隔的数据导出为.csv或.xls?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用BeautifulSoup中的Python将单行中多列分隔的数据导出为.csv或.xls?相关的知识,希望对你有一定的参考价值。
我目前将这些数据存储为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 |
+------------+---+------+---+------+---+------+----------+-------------+
......等表示来自上述结果变量的剩余数据。我没有在这里写出来以避免混乱。
那么,我应该使用哪些模块以及如何操作?请注意,我是一个完整的Python新手。我只知道一些PHP的东西,但说实话,我开始喜欢py。
第一个问题是您需要知道奖品之间的分割位置。没有看到Special Prize
文本,这将是困难的。另一种方法是使用find_all()
来发现td
和th
元素。列表理解另外仅添加非空单元格。这将生成包含您需要的所有数据的单个列表。
cols
包含所需列的列表。手动填写第1,第2和第3奖项,因为这些条目应该是固定的。然后使用循环将相应的字母和奖品添加到最后四列。
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文件在加载到电子表格包时具有以下类型的格式:
这里使用了很多Python技术,需要一段时间才能理解。例如,grouper
是itertools recipes之一。 islice()
是一种迭代对象而不需要从第一个位置开始的方法。
CSV文件的最终输出是使用Python的CSV库完成的。这会将行列表转换为格式正确的输出行。由于数据采用列格式,因此需要一个技巧将列表转换为行列表,这是使用zip_longest()
完成的。
如果将print语句添加到代码中以查看数据的样子,这可能会有所帮助。
注意,要将数据直接保存为Excel格式(.xlsx),您需要安装另一个库,例如,您可以使用openpyxl或xlwt。
以上是关于如何使用BeautifulSoup中的Python将单行中多列分隔的数据导出为.csv或.xls?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 python 中使用 beautifulsoup4 来抓取标签中的内容
如何在python中忽略BeautifulSoup解析器中的换行符