python - 如何使用 python 和 bs4 修复抓取 web 表输出 csv

标签 python csv web-scraping beautifulsoup scrape

请帮帮我,, 我想在“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 selectorcenter 元素来选择第一列条形码中心

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)
<小时/>

补充阅读:

  1. css selectors

关于python - 如何使用 python 和 bs4 修复抓取 web 表输出 csv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57802703/

相关文章:

mysql - 如何使用 codeigniter 导入 CSV 文件并将数据插入到多个表中?

c# - 如何消除尾随的空行/列

Python如何以C速度循环遍历numpy中的数组并存储一些位置

python - 如何在不迭代的情况下计算pymongo聚合游标

c++ - Python 到 C++ 字符编码

javascript - (Javascript) 当属性不存在时,如何使用 csv 中的标题和空字符串将对象属性获取到 csv?

python - 查找集列表之间的交集

javascript - 干刮点击 "load more button"

python - 通过机器学习从网页中提取信息

javascript - 如何使用 jQuery 和 XPath 抓取网页?