2017-07-15 85 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事件加載了你可以指定事件等待硒。