我试图从一个网站上抓取41个项目和他们的价格清单。但是我的输出csv缺少页面末尾的2-3个项目。原因是,一些设备的价格与其他设备的价格不同。在我的代码中,递归是对名称和价格一起运行的,对于在不同类中提到价格的项目,它将从下一个设备中获取价格值。因此,它跳过最后2-3个项目,因为那些设备的价格已经在以前的设备的递归中输入。参考代码如下:
# -*- coding: cp1252 -*-
import csv
import urllib2
import sys
import time
from bs4 import BeautifulSoup
page = urllib2.urlopen('http://www.att.com/shop/wireless/devices/smartphones.deviceListGridView.xhr.flowtype-NEW.deviceGroupType-Cellphone.paymentType-postpaid.packageType-undefined.html?taxoStyle=SMARTPHONES&showMoreListSize=1000').read()
soup = BeautifulSoup(page)
soup.prettify()
with open('AT&T_2012-12-28.csv', 'wb') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=',')
spamwriter.writerow(["Date","Month","Day of Week","Device Name","Price"])
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:
spamwriter.writerow([time.strftime("%Y-%m-%d"),time.strftime("%B"),time.strftime("%A") ,unicode(item.string).encode('utf8').replace('â„¢','').replace('®','').strip(),textcontent])价格通常在listGrid-price下提及,但对于一些2-3项目,这是在目前的价格是在listGrid-price-outOfStock下的价格,我需要包括这也在我的递归,以便正确的价格来之前的项目和循环运行的所有设备。
请原谅我的无知,因为我是编程新手
发布于 2012-12-28 17:58:19
您可以使用比较器函数进行自定义比较,并将其传递给您的findAll()。
因此,如果您使用prices分配将线路修改为:
prices = soup.findAll('div', class_=match_both)并将该函数定义为:
def match_both(arg):
if arg == "listGrid-price" or arg == "listGrid-price-outOfStock":
return True
return False(函数可以变得更简洁,这里的冗长只是为了让你了解它是如何工作的)
因此,它将比较这两种情况,并在任何情况下返回匹配。
更多信息可以在documentation上找到。( has_six_characters变体)
现在,既然您还询问了如何排除特定文本。
findAll()的text参数也可以有自定义的比较器。因此,在这种情况下,您不希望显示Write a review的文本匹配,从而导致价格与文本之间的变化。
因此,您编辑的脚本将排除审查部分:
# -*- coding: cp1252 -*-
import csv
import urllib2
import sys
import time
from bs4 import BeautifulSoup
def match_both(arg):
if arg == "listGrid-price" or arg == "listGrid-price-outOfStock":
return True
return False
def not_review(arg):
if not arg:
return arg
return "Write a review" not in arg
page = urllib2.urlopen('http://www.att.com/shop/wireless/devices/smartphones.deviceListGridView.xhr.flowtype-NEW.deviceGroupType-Cellphone.paymentType-postpaid.packageType-undefined.html?taxoStyle=SMARTPHONES&showMoreListSize=1000').read()
soup = BeautifulSoup(page)
soup.prettify()
with open('AT&T_2012-12-28.csv', 'wb') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=',')
spamwriter.writerow(["Date","Month","Day of Week","Device Name","Price"])
items = soup.findAll('a', {"class": "clickStreamSingleItem"},text=not_review)
prices = soup.findAll('div', class_=match_both)
for item, price in zip(items, prices):
textcontent = u' '.join(price.stripped_strings)
if textcontent:
spamwriter.writerow([time.strftime("%Y-%m-%d"),time.strftime("%B"),time.strftime("%A") ,unicode(item.string).encode('utf8').replace('™','').replace('®','').strip(),textcontent])https://stackoverflow.com/questions/14067530
复制相似问题