【问题标题】:Exporting Beautiful Soup table scrape results to CSV将 Beautiful Soup 表抓取结果导出到 CSV
【发布时间】:2015-05-03 08:35:39
【问题描述】:

这里是 Python 初学者,首先尝试使用 CSV 模块导出抓取结果。有问题的脚本返回几个表格元素,只对每个返回产品的“价格”和“mfr-no”感兴趣。基本上,每个元素只需要 2 列。

我确定在尝试写入 csv 时我做错了什么,只是不确定是什么。我的桌面上有一个名为“test”的空 .csv 文件,我正在尝试将所有内容写入该文件,并且我尝试在 SE 上复制其他“写入 csv”示例的相同格式,但无济于事。任何意见表示赞赏。

from bs4 import BeautifulSoup

import csv
import requests

csvfile = "test.csv"
url = "http://www.dabs.com/category/computing/11001"
base_url = "http://www.dabs.com"
page_array = []

html = requests.get(url)
soup = BeautifulSoup(html.content, "html.parser")
Product_table = soup.findAll("table")
Products = Product_table[0].findAll("tr")

if len(soup.findAll('tr')) > 0:
    Products = Products[1:]

for row in Products:
    cells = row.find_all('td')
    data = {
        'description' : cells[0].get_text(),
        'price' : cells[1].get_text()
    }
    print row

with open(csvfile, row) as csvfile:
    link_writer = csv.writer(csvfile)
    for val in row:
        link_writer.writerow(val)

【问题讨论】:

    标签: python csv web-scraping beautifulsoup export-to-csv


    【解决方案1】:

    你需要打开写而不是传递一个可迭代对象:

    with open(csvfile, "w") as csvfile: # w opens for writing
    

    如果您想从循环中写入项目,您应该在外部打开并在循环中写入:

    with open(csvfile, "w") as csvfile:
        link_writer = csv.writer(csvfile)
        for row in Products:
            cells = row.find_all('td')
            data = {
                'description' : cells[0].get_text(),
                'price' : cells[1].get_text()
            }
           # write what you need
    

    您的代码也没有找到任何东西,以获取制造商编号和价格:

    html = requests.get(url)
    soup = BeautifulSoup(html.content, "html.parser")
    product_table = soup.find("table")
    tds = product_table.find_all('td')
    
    
    with open(csvfile, "w") as csvfile:
        link_writer = csv.writer(csvfile)
        for tag in tds:
            mfr = tag.find("span")
            if mfr:
                print(mfr.text)
    
    Mfr#: FK3-UK
    £30.00
    Mfr#: PDW0AE-00900PEN
    £99.99
    Mfr#: FORCE K7
    £39.99
    Mfr#: X551MAV-BING-SX1017B
    £229.99
    Mfr#: VE228TR
    £79.99
    Mfr#: QQ2-00038
    £59.94
    Mfr#: M6900
    £18.00
    Mfr#: MCB4370500C2/04/1
    £51.39
    Mfr#: 79G-03549
    £94.99
    Mfr#: FQC-08289
    £113.18
    Mfr#: WN7-00614
    £76.32
    Mfr#: GFC-02733
    £69.99
    Mfr#: 2LF-00021
    £19.78
    Mfr#: T5D-01574
    £169.72
    Mfr#: X555LA-XX273H
    £399.99
    Mfr#: FQC-06949
    £109.99
    Mfr#: 10DR000TUK
    £279.99
    Mfr#: 10AW008NUK
    £268.44
    Mfr#: MCF3QUK
    £179.98
    Mfr#: K3X03EA#ABU
    £253.45
    Mfr#: 10DR001EUK
    £348.82
    Mfr#: 9H.LA2LB.DPE
    £76.41
    Mfr#: 51MF1600AA001
    £29.98
    Mfr#: G7V83EA REFURB
    £199.99
    Mfr#: 62151
    £27.99
    

    所以要创建一个以 mfr-nr 为键、价格为值的字典:

    product_table = soup.find("table")
    tds = product_table.find_all('td')
    
    data = []
    for tag in tds:
        mfr = tag.find("span")
        if mfr: # make sure we have test to get
            data.append(mfr.text)
    
    it = iter(data) # create iterator 
    # will create key/value pairings by getting every second element as key and every second element as value starting from 0 and 1 respectively.
    data_dict  = dict(zip(it, it))
    
    print(data_dict)
    {'Mfr#: FQC-08289': '£113.18', 'Mfr#: 62151': '£27.99', 'Mfr#: VE228TR': '£79.99', 'Mfr#: GFC-02733': '£69.99', 'Mfr#: FK3-UK': '£30.00', 'Mfr#: WN7-00614': '£76.32', 'Mfr#: 10DR001EUK': '£348.82', 'Mfr#: 51MF1600AA001': '£29.98', 'Mfr#: FORCE K7': '£39.99', 'Mfr#: 10DR000TUK': '£279.99', 'Mfr#: 2LF-00021': '£19.78', 'Mfr#: M6900': '£18.00', 'Mfr#: T5D-01574': '£169.72', 'Mfr#: MCB4370500C2/04/1': '£51.39', 'Mfr#: 10AW008NUK': '£268.44', 'Mfr#: PDW0AE-00900PEN': '£99.99', 'Mfr#: G7V83EA REFURB': '£199.99', 'Mfr#: 79G-03549': '£94.99', 'Mfr#: K3X03EA#ABU': '£253.45', 'Mfr#: FQC-06949': '£109.99', 'Mfr#: X551MAV-BING-SX1017B': '£229.99', 'Mfr#: X555LA-XX273H': '£399.99', 'Mfr#: QQ2-00038': '£59.94', 'Mfr#: MCF3QUK': '£179.98', 'Mfr#: 9H.LA2LB.DPE': '£76.41'}
    

    最后写入csv:

    with open(csvfile, "w") as csvfile:
        link_writer = csv.writer(csvfile)
        for tup in data_dict.items():
            link_writer.writerow(tup) # write key and value mfr/price in each column 
    

    输出如下:

    Mfr#: 10DR001EUK,£348.82
    Mfr#: WN7-00614,£76.32
    Mfr#: FQC-06949,£109.99
    Mfr#: 2LF-00021,£19.78
    Mfr#: MCB4370500C2/04/1,£51.39
    Mfr#: PDW0AE-00900PEN,£99.99
    Mfr#: GFC-02733,£69.99
    Mfr#: G7V83EA REFURB,£199.99
    Mfr#: X555LA-XX273H,£399.99
    Mfr#: FK3-UK,£30.00
    Mfr#: QQ2-00038,£59.94
    Mfr#: T5D-01574,£169.72
    Mfr#: 51MF1600AA001,£29.98
    Mfr#: 62151,£27.99
    Mfr#: FQC-08289,£113.18
    Mfr#: K3X03EA#ABU,£253.45
    Mfr#: VE228TR,£79.99
    Mfr#: 9H.LA2LB.DPE,£76.41
    Mfr#: 10DR000TUK,£279.99
    Mfr#: FORCE K7,£39.99
    Mfr#: X551MAV-BING-SX1017B,£229.99
    Mfr#: 10AW008NUK,£268.44
    Mfr#: MCF3QUK,£179.98
    Mfr#: 79G-03549,£94.99
    Mfr#: M6900,£18.00
    

    如果您不想在输出中使用 Mfr#: 部分,只需使用 str.split:

    data = []
    for tag in tds:
        mfr = tag.find("span")
        if mfr:
            data.append(mfr.text.split(":")[-1].strip())
    

    所以您的 csv 将如下所示:

    FK3-UK,£30.00
    2LF-00021,£19.78
    G7V83EA REFURB,£199.99
    T5D-01574,£169.72
    FQC-06949,£109.99
    10DR001EUK,£348.82
    FQC-08289,£113.18
    M6900,£18.00
    10DR000TUK,£279.99
    VE228TR,£79.99
    WN7-00614,£76.32
    62151,£27.99
    MCF3QUK,£179.98
    FORCE K7,£39.99
    51MF1600AA001,£29.98
    X551MAV-BING-SX1017B,£229.99
    GFC-02733,£69.99
    9H.LA2LB.DPE,£76.41
    79G-03549,£94.99
    QQ2-00038,£59.94
    PDW0AE-00900PEN,£99.99
    K3X03EA#ABU,£253.45
    MCB4370500C2/04/1,£51.39
    10AW008NUK,£268.44
    X555LA-XX273H,£399.99
    

    【讨论】:

    • @user3093445,没有问题。解析时总是有几种不同的方法可以得到你需要的东西,如果可能的话,尝试一步获取关联值始终是最好的方法,这样才能正确排列。
    猜你喜欢
    • 2020-04-22
    • 1970-01-01
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多