请帮帮我,, 我想在“td”、“Barcode”和“nama produk”中获取 2 个数据,但我得到的数据非常糟糕。我应该修复什么?
import csv
import requests
from bs4 import BeautifulSoup
outfile = open("dataaa.csv","w",newline='')
writer = csv.writer(outfile)
page = 0
while page < 3 :
url = "http://ciumi.com/cspos/barcode-ritel.php?page={:d}".format(page)
response = requests.get(url)
tree = BeautifulSoup(response.text, 'html.parser')
page += 1
table_tag = tree.select("table")[0]
tab_data = [[item.text for item in row_data.select("tr")]
for row_data in table_tag.select("td")]
for data in tab_data:
writer.writerow(data)
print(table_tag)
print(response, url, ' '.join(data))
import fileinput
seen = set()
for line in fileinput.FileInput('dataaa.csv', inplace=1):
if line in seen: continue
seen.add(line)
print (line)
我需要改进哪些方面才能获得漂亮的结果?
最佳答案
看起来页面从 1 开始,所以我的范围循环从那里开始。然后你可以使用Session对象以提高重用连接的效率。如果您明智地选择 css 选择器,则所有过滤都可以在该级别完成,然后您只使用检索到的所需元素。您可以使用更轻量级的 csv
而不是更重的 pandas
导入。
需要bs4 4.7.1+作为杠杆:has
伪选择器。
快速解释:
以下内容通过仅定位带有 type selector 的 center
元素来选择第一列条形码中心
soup.select('center')
然后
soup.select('td:has(center) + td')
使用 adjacent sibling combinator 选择第二列获取具有 center
子元素的左侧表格单元格 (td) 旁边的右侧相邻表格单元格。
检索到的标签列表的 .text
在列表理解中被提取和剥离,然后它们被压缩并再次转换为列表;并附加到最终列表结果
,稍后循环写入到 csv。
CSS 选择器保持最小,以便更快地匹配。
<小时/>import requests, csv
from bs4 import BeautifulSoup as bs
results = []
with requests.Session() as s:
for page in range(1,4): #pages start at 1 and assuming you actually want first 3
r = s.get(f'http://ciumi.com/cspos/barcode-ritel.php?page={page}')
soup = bs(r.content, 'lxml')
results += list(zip([i.text.strip() for i in soup.select('center')] , [i.text.strip() for i in soup.select('td:has(center) + td')]))
with open("data.csv", "w", encoding="utf-8-sig", newline='') as csv_file:
w = csv.writer(csv_file, delimiter = ",", quoting=csv.QUOTE_MINIMAL)
w.writerow(['Barcode','Nama Produk'])
for line in results:
w.writerow(line)
<小时/>
补充阅读:
关于python - 如何使用 python 和 bs4 修复抓取 web 表输出 csv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57802703/