使用spamwriter.writerow在两列csv中使用漂亮的汤来输出数据的问题

时间:2012-12-20 08:55:34

标签: csv python-2.7 beautifulsoup

我正在使用漂亮的汤从网站上抓取2组数据,我希望它们并排输出2列中的csv文件。我正在使用spamwriter.writerow([x,y])参数,但我认为由于我的递归结构中的一些错误,我在我的csv文件中得到了错误的输出。以下是推荐代码:

import csv
import urllib2
import sys  
from bs4 import BeautifulSoup
page = urllib2.urlopen('http://www.att.com/shop/wireless/devices/smartphones.html').read()
soup = BeautifulSoup(page)
soup.prettify()
with open('Smartphones_20decv2.0.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=',')        
    for anchor in soup.findAll('a', {"class": "clickStreamSingleItem"},text=True):
        if anchor.string:
            print unicode(anchor.string).encode('utf8').strip()         

    for anchor1 in soup.findAll('div', {"class": "listGrid-price"}):
        textcontent = u' '.join(anchor1.stripped_strings)
        if textcontent:
            print textcontent
            spamwriter.writerow([unicode(anchor.string).encode('utf8').strip(),textcontent])

我在csv中获得的输出是:

Samsung Focus® 2 (Refurbished) $99.99
Samsung Focus® 2 (Refurbished) $99.99 to $199.99 8 to 16 GB
Samsung Focus® 2 (Refurbished) $0.99
Samsung Focus® 2 (Refurbished) $0.99
Samsung Focus® 2 (Refurbished) $149.99 to $349.99 16 to 64 GB

问题是我在第1列中只获得了1个设备名称,而不是所有设备的价格。 请原谅我的无知,因为我不熟悉编程。

1 个答案:

答案 0 :(得分:1)

您使用的是anchor.string,而不是archor1anchor是上一循环中的 last 项,而不是当前循环中的项。

也许使用更清晰的变量名称有助于避免混淆;或许使用singleitemgridprice

虽然可能是我误解了你想要将每个anchor1与相应的anchor合并。您必须将它们一起循环,可能使用zip()

items = soup.findAll('a', {"class": "clickStreamSingleItem"},text=True)
prices = soup.findAll('div', {"class": "listGrid-price"})
for item, price in zip(items, prices):
    textcontent = u' '.join(price.stripped_strings)
    if textcontent:
        print textcontent
        spamwriter.writerow([unicode(item.string).encode('utf8').strip(),textcontent])

通常它应该更容易在父表行上循环,然后在循环中找到该行内的单元格。但zip()也应该有效,只要clickStreamSingleItem单元符合listGrid-price匹配即可。