WebCrawler,只有少数商品有折扣价 - 索引错误
Posted
技术标签:
【中文标题】WebCrawler,只有少数商品有折扣价 - 索引错误【英文标题】:WebCrawler, only few items have discounted prices - index error 【发布时间】:2018-04-17 21:31:29 【问题描述】:我是编程新手,正在尝试用 python 构建我的第一个小型网络爬虫。
目标:爬取产品列表页面 - 抓取品牌名称、商品名称、原价和新价格 - 保存在 CSV 文件中
状态:我已经设法获得品牌名称、商品名称以及原价,并将它们按正确的顺序放入列表中(例如 10 种产品)。由于所有商品都有品牌名称、描述和价格,我的代码将它们以正确的顺序放入 csv 中。
代码:
import bs4
from urllib.request import urlopen as uReq
from bs4 import BeautifulSoup as soup
myUrl = 'https://www.zalando.de/rucksaecke-herren/'
#open connection, grabbing page, saving in page_html and closing connection
uClient = uReq(myUrl)
page_html = uClient.read()
uClient.close()
#Datatype, html paser
page_soup = soup(page_html, "html.parser")
#grabbing information
brand_Names = page_soup.findAll("div","class": "z-nvg-cognac_brandName-2XZRz z-nvg-cognac_textFormat-16QFn")
articale_Names = page_soup.findAll ("div","class": "z-nvg-cognac_articleName--arFp z-nvg-cognac_textFormat-16QFn")
original_Prices = page_soup.findAll("div","class": "z-nvg-cognac_originalPrice-2Oy4G")
new_Prices = page_soup.findAll("div","class": "z-nvg-cognac_promotionalPrice-3GRE7")
#opening a csv file and printing its header
filename = "XXX.csv"
file = open(filename, "w")
headers = "BRAND, ARTICALE NAME, OLD PRICE, NEW PRICE\n"
file.write(headers)
#How many brands on page?
products_on_page = len(brand_Names)
#Looping through all brands, atricles, prices and writing the text into the CSV
for i in range(products_on_page):
brand = brand_Names[i].text
articale_Name = articale_Names[i].text
price = original_Prices[i].text
new_Price = new_Prices[i].text
file.write(brand + "," + articale_Name + "," + price.replace(",",".") + new_Price.replace(",",".") +"\n")
#closing CSV
file.close()
问题:我正在努力将折扣价放入我的 csv 中正确的位置。并非每件商品都有折扣,我目前看到我的代码有两个问题:
我使用 .findAll 来查找网站上的信息 - 由于折扣产品少于总产品,我的 new_Prices 包含的价格更少(例如 10 种产品的 3 个价格)。如果我能够将它们添加到列表中,我假设它们会出现在前 3 行中。如何确保将 new_Price 添加到正确的产品中?
我收到“索引错误:列表索引超出范围”错误,我认为这是因为我正在循环浏览 10 个产品,但是对于 new_Prices,我比其他产品更快地到达终点清单?这有意义吗,我的假设是否正确?
我非常感谢任何帮助。
谢谢,
索斯滕
【问题讨论】:
请勿贴代码截图,将相关代码复制到代码块中。 也发布一个输入示例 @bgse 将代码更新为块 @Guilherme 不确定我是否理解,您能否详细说明?输入示例是什么意思 @ThorsteinTorento 我相信 Guilherme 要求您发布指向相关网站的链接。这将帮助我们了解您的代码中的哪些问题 【参考方案1】:由于某些项目没有'div.z-nvg-cognac_promotionalPrice-3GRE7'
标记,因此您无法可靠地使用列表索引。
但是,您可以选择所有容器标签 ('div.z-nvg-cognac_infoContainer-MvytX'
) 并使用 find
选择每个项目上的标签。
from urllib.request import urlopen
from bs4 import BeautifulSoup as soup
import csv
my_url = 'https://www.zalando.de/sporttaschen-reisetaschen-herren/'
client = urlopen(my_url)
page_html = client.read().decode(errors='ignore')
page_soup = soup(page_html, "html.parser")
headers = ["BRAND", "ARTICALE NAME", "OLD PRICE", "NEW PRICE"]
filename = "test.csv"
with open(filename, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(headers)
items = page_soup.find_all(class_='z-nvg-cognac_infoContainer-MvytX')
for item in items:
brand_names = item.find(class_="z-nvg-cognac_brandName-2XZRz z-nvg-cognac_textFormat-16QFn").text
articale_names = item.find(class_="z-nvg-cognac_articleName--arFp z-nvg-cognac_textFormat-16QFn").text
original_prices = item.find(class_="z-nvg-cognac_originalPrice-2Oy4G").text
new_prices = item.find(class_="z-nvg-cognac_promotionalPrice-3GRE7")
if new_prices is not None:
new_prices = new_prices.text
writer.writerow([brand_names, articale_names, original_prices, new_prices])
如果您希望每页获得超过 24 个项目,则必须使用运行 js 的客户端,例如 selenium
。
from selenium import webdriver
from bs4 import BeautifulSoup as soup
import csv
my_url = 'https://www.zalando.de/sporttaschen-reisetaschen-herren/'
driver = webdriver.Firefox()
driver.get(my_url)
page_html = driver.page_source
driver.quit()
page_soup = soup(page_html, "html.parser")
...
脚注:
函数和变量的naming conventions 是小写的,带有下划线。
读取或写入 csv 文件时,最好使用 csv
lib。
处理文件时可以使用with
语句。
【讨论】:
嗨@t.m.adam,非常感谢您的反馈和建议!我自己终于到了那里,但你的代码看起来更整洁!我注意到的一个想法是页面一定已经改变,因为页面上现在有超过 24 个项目。奇怪的是,当运行爬虫时,它只拾取 24 个项目。知道为什么吗? 是的,剩下的都是js加载的。如果您在浏览器中禁用 js 并访问该页面,则可以对此进行测试。您可以使用selenium
或有时通过 ajax api 获取所有项目。当我有空闲时间时,我会发布一个示例。
嗨@t.m.adam,太好了!谢谢!出于兴趣,为什么要以这种方式设置页面(加载这 24 个项目,然后通过 JS 加载其余项目)?谢谢,T
我不知道,我第一次看到这样的东西。对于同一组中的所有项目,它应该是静态 html 或 js。无论如何,您是否设法使用硒获得了结果?
嗨@t.m.adam 有趣! :) 下班后我会试一试 - 只是在午休时间看了一下!我会及时通知你以上是关于WebCrawler,只有少数商品有折扣价 - 索引错误的主要内容,如果未能解决你的问题,请参考以下文章