2017-07-15 70 views
0

不确定如何正确地说出问题。Python - beautifulSoup无法迭代重复块

我试图通过与树的HTML文档类似的

div(unique-class) 
|-a 
|-h4 
|-div(class-a) 
|-div(class-b) 
|-div(class-c) 
|-p 

等来分析,它会继续。我只列出了我需要的几件物品。这是很多兄弟姐妹层次结构,都存在于一个div内。

在过去的几个小时里,我一直在BeautifulSoup上工作过很长时间,在这个例子中,我终于有了一个我想解析的工作版本(测试版)。

from bs4 import BeautifulSoup 
import urllib2 
import csv 
file = "C:\\Python27\\demo.html" 

soup = BeautifulSoup (open(file), 'html.parser') 
#(page, 'html.parser') 

#Let's pull prices 
names = [] 
pricing = [] 
discounts = [] 

for name in soup.find_all('div', attrs={'class': 'unique_class'}): 
names.append(name.h4.text) 
for price in soup.find_all('div', attrs={'class': 'class-b'}): 
pricing.append(price.text) 
for discount in soup.find_all('div', attrs={'class': 'class-a'}): 
discounts.append(discount.text) 
ofile = open('output2.csv','wb') 
fieldname = ['name', 'discountPrice', 'originalPrice'] 
writer = csv.DictWriter(ofile, fieldnames = fieldname) 
writer.writeheader() 
for i in range(len(names)): 
print (names[i], pricing[i], discounts[i]) 

writer.writerow({'name': names[i], 'discountPrice':pricing[i], 'originalPrice': discounts[i]}) 
ofile.close() 

正如你可以告诉它它从上到下迭代并追加到每个不同的数组。问题是,如果我正在迭代,比方说,30,000个项目和网站可以自行修改(我们将在JS框架上说一个ScoreBoard应用程序),到我第二次迭代时,订单可能会有改变。 (当我键入此我意识到这种情况下居然会需要更多的变量,因为BS我将“抓”的网站加载的时间,但认为问题依然存在。)

我相信我需要利用内next_sibling功能BS4,但当我这样做时,我开始捕获我没有指定的项目,因为我无法将“班级”应用于兄弟姐妹。

更新

的另一个问题试图做一个循环内的循环,找到3个孩子,我需要下unique-class是我最终会被列出的所有名称的第一个价格时,我鼓励。

更新 - 添加样本HTML

<div class="unique_class"> 
    <h4>World</h4> 
    <div class="class_b">$1.99</div> 
    <div class="class_a">$1.99</div> 
</div> 
<div class="unique_class"> 
    <h4>World2</h4> 
    <div class="class_b">$2.99</div> 
    <div class="class_a">$2.99</div> 
</div> 
<div class="unique_class"> 
    <h4>World3</h4> 
    <div class="class_b">$3.99</div> 
    <div class="class_a">$3.99</div> 
</div> 
<div class="unique_class"> 
    <h4>World4</h4> 
    <div class="class_b">$4.99</div> 
    <div class="class_a">$3.99</div> 
</div> 

我还发现一个解决方法,并提交答案进行优化 - 位于CodeReview

+0

你真的尝试过调用'(open(url)...'而不是'(open(file)...'吗?'汤'变量一旦被定义就不应该改变 - 对象BeautifulSoup创建是静态的 – snapcrack

+0

对于我来说,至少有一个有点难以回答的问题,因为我无法检查你想解析的实际的HTML,而且,虽然你说这是工作代码,但我怀疑这行'soup = BeautifulSoup(open (file),'html.parser')'会做你期望的事情。你想要什么特定的输出? –

+0

@BillBell完全公平点 - 我必须做很多操作才能获得html.parser。附加的示例,以及我获得的创可贴版本的代码审查链接。 – DNorthrup

回答

1

如果网站您正在寻找刮数据从使用JS你可能想要使用硒并使用其page_source方法提取加载的JS页面的快照,然后可以加载到BS。

from selenium import webdriver 
driver = webdriver.PhantomJS() 
driver.get(<url>) 
page = driver.page_source 

然后你可以用BS解析JS加载页面“ 如果你想等待其它JS事件加载了你可以指定事件等待硒。