2014-06-09 13 views
5

Tôi muốn tìm nạp dữ liệu từ một url khác mà tôi đang sử dụng urllib và Beautiful Soup, Dữ liệu của tôi nằm trong thẻ bảng (mà tôi đã tìm ra bằng cách sử dụng Bảng điều khiển Firefox). Nhưng khi tôi cố gắng lấy bảng bằng cách sử dụng id của mình, kết quả là None, Sau đó, tôi đoán bảng này phải được thêm động thông qua một số mã js.Tìm nạp dữ liệu của các biến bên trong thẻ tập lệnh bằng Python hoặc Nội dung được thêm từ js

Tôi đã thử cả hai trình phân tích cú pháp 'lxml', 'html5lib' nhưng vẫn không thể lấy dữ liệu bảng đó.

Tôi cũng đã cố gắng một điều nữa:

web = urllib.urlopen("my url") 
html = web.read() 
soup = BeautifulSoup(html, 'lxml') 
js = soup.find("script") 
ss = js.prettify() 
print ss 

Kết quả:

<script type="text/javascript"> 
myPage = 'ETFs'; 
     sectionId = 'liQuotes'; //section tab 
     breadCrumbId = 'qQuotes'; //page 
     is_dartSite = "quotes"; 
     is_dartZone = "news"; 
     propVar = "ETFs"; 
</script> 

Nhưng bây giờ tôi không biết làm thế nào tôi có thể nhận được dữ liệu của các biến js.

Bây giờ tôi có hai tùy chọn để nhận được các biến js, bất kỳ một trong số chúng có thể hoàn thành nhiệm vụ của tôi nhưng tiếc là tôi không biết cách làm như thế này. một trong những vấn đề.

Cảm ơn

+1

Không có điểm nào khi đoán javascript có tạo nội dung bảng hay không - bạn cần phải xác nhận điều đó trước tiên. URL có thể truy cập công khai không? Nếu vậy, nó là cái gì? – mhawke

+0

Có Tôi xác nhận dữ liệu bảng được tạo từ mã js, bạn có thể kiểm tra tại đây http://www.nasdaq.com/quotes/nasdaq-financial-100-stocks.aspx. – Inforian

Trả lời

7

EDIT

này sẽ làm các trick sử dụng re module để trích xuất các dữ liệu và tải nó như JSON:

import urllib 
import json 
import re 
from bs4 import BeautifulSoup 

web = urllib.urlopen("http://www.nasdaq.com/quotes/nasdaq-financial-100-stocks.aspx") 
soup = BeautifulSoup(web.read(), 'lxml') 
data = soup.find_all("script")[19].string 
p = re.compile('var table_body = (.*?);') 
m = p.match(data) 
stocks = json.loads(m.groups()[0]) 

>>> for stock in stocks: 
...  print stock 
... 
[u'ASPS', u'Altisource Portfolio Solutions S.A.', 116.96, 2.2, 1.92, 86635, u'N', u'N'] 
[u'AGNC', u'American Capital Agency Corp.', 23.76, 0.13, 0.55, 3184303, u'N', u'N'] 
. 
. 
. 
[u'ZION', u'Zions Bancorporation', 29.79, 0.46, 1.57, 2154017, u'N', u'N'] 

Vấn đề ở đây là các thẻ script bù đắp được mã hóa cứng và không có cách nào đáng tin cậy để định vị nó trong trang. Các thay đổi đối với trang có thể phá vỡ mã của bạn.

câu trả lời ORIGINAL

Thay vì cố gắng sàng lọc cạo dữ liệu, bạn có thể tải về một đại diện CSV của cùng một dữ liệu từ http://www.nasdaq.com/quotes/nasdaq-100-stocks.aspx?render=download.

Sau đó, sử dụng mô-đun Python csv để phân tích và xử lý mô-đun. Không chỉ thuận tiện hơn, nó sẽ là một giải pháp linh hoạt hơn bởi vì bất kỳ thay đổi nào đối với HTML đều có thể dễ dàng phá vỡ mã cạo màn hình của bạn.

Ngược lại, nếu bạn nhìn vào HTML thực tế bạn sẽ thấy rằng các dữ liệu có sẵn trong trang trong thẻ script sau:

<script type="text/javascript">var table_body = [["ATVI", "Activision Blizzard, Inc", 20.92, 0.21, 1.01, 6182877, .1, "N", "N"], 
["ADBE", "Adobe Systems Incorporated", 66.91, 1.44, 2.2, 3629837, .6, "N", "N"], 
["AKAM", "Akamai Technologies, Inc.", 57.47, 1.57, 2.81, 2697834, .3, "N", "N"], 
["ALXN", "Alexion Pharmaceuticals, Inc.", 170.2, 0.7, 0.41, 659817, .1, "N", "N"], 
["ALTR", "Altera Corporation", 33.82, -0.06, -0.18, 1928706, .0, "N", "N"], 
["AMZN", "Amazon.com, Inc.", 329.67, 6.1, 1.89, 5246300, 2.5, "N", "N"], 
.... 
["YHOO", "Yahoo! Inc.", 35.92, 0.98, 2.8, 18705720, .9, "N", "N"]]; 
+0

Thực ra, xin lỗi, CSV không có sẵn cho URL mà bạn đã đăng, trong trường hợp đó bạn sẽ phải giải nén nó khỏi biến javascript.Có vẻ như sau: '

2

Chỉ cần để thêm vào @mhawke 's câu trả lời, chứ không phải là hardcoding bù đắp của thẻ script, bạn lặp qua tất cả các thẻ script và khớp với thẻ khớp với mẫu của bạn;

web = urllib.urlopen("http://www.nasdaq.com/quotes/nasdaq-financial-100-stocks.aspx") 
pattern = re.compile('var table_body = (.*?);') 

soup = BeautifulSoup(web.read(), "lxml") 
scripts = soup.find_all('script') 
for script in scripts: 
    if(pattern.match(str(script.string))): 
     data = pattern.match(script.string) 
     stock = json.loads(data.groups()[0]) 
     print stock 
Các vấn đề liên quan