2010-08-06 38 views
6

Tôi đang sử dụng RCurl trong R để thử và tải xuống dữ liệu từ một trang web, nhưng tôi đang gặp khó khăn khi tìm ra URL cần sử dụng. Đây là trang web:Tìm địa chỉ web của liên kết Javascript

http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX

Xem cách ở phía trên bên phải, phía trên tấm hiển thị, có một liên kết để tải dữ liệu như một tập tin .csv? Tôi đã tự hỏi nếu có một cách để tìm một địa chỉ HTTP thường xuyên cho rằng .csv tập tin, bởi vì RCurl không thể xử lý các lệnh Javascript.

Trả lời

7

Nhấp vào liên kết Tải về thực hiện tác phẩm này của JavaScript:

__doPostBack('ctl00$MainPageLeft$MainPageContent$ExportHoldings1$LinkButton1','') 

Đó __doPostBack chức năng dường như chỉ đơn giản là điền vào một vài lĩnh vực hình thức ẩn trên trang đó sau đó gửi một yêu cầu POST.

Một trình duyệt nhanh cho thấy RCurl có khả năng gửi yêu cầu POST. Vì vậy, những gì bạn cần làm là tìm trong nguồn của trang đó, tìm biểu mẫu có tên "aspnetForm", lấy tất cả các trường từ biểu mẫu đó và tạo yêu cầu POST của riêng bạn gửi các trường tới URL hành động (http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX)).

Không thể đảm bảo điều này sẽ hoạt động. Dường như có một trường biểu mẫu ẩn có tên là __VIEWSTATE dường như mã hóa một số thông tin và tôi không biết các yếu tố này như thế nào.

+0

Tuyệt vời-- bạn đã tìm tài liệu về cách gửi yêu cầu POST cho Javascript bằng RCurl ở đâu? –

+0

http://www.omegahat.org/RCurl/installed/RCurl/html/postForm.html – Jeff

1

Đây chắc chắn là cách để lấy tệp .csv trong RCurl, nhưng tôi có thể ' t tìm ra những lĩnh vực hình thức tôi muốn sử dụng trong getForm để làm cho nó hoạt động. Tôi có nên sử dụng các trường từ lệnh doPostBack được đính kèm với liên kết "Tải xuống" trên trang hay tôi nên sử dụng các trường từ aspnetForm trên trang nguồn. Chỉ để tham khảo, trường aspnetForm mà chúng tôi quan tâm là:

" tên biểu mẫu =" aspnetForm "method =" post "action =" holdings.aspx? Ticker = PGX "id =" aspnetForm "style =" margin: 0px " "

... và yêu cầu postForm tôi chỉ cố gắng đó không làm việc là

postForm (" http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX", "tên dạng" = "aspnetForm", "phương pháp" = " post "," action "=" holdings.aspx? ticker = PGX "," id "=" aspnetForm "," style "=" margin: 0px ")

Cảm ơn tất cả sự giúp đỡ!

+0

Bạn sẽ bắt đầu với các trường trong biểu mẫu aspnetForm, sau đó ghi đè bất kỳ điều gì ở trong đó với các giá trị mà hàm doPostBack chèn vào các trường ẩn.Bởi vì những gì doPostBack thực hiện về cơ bản là lấy biểu mẫu hiện có và điền vào hai trường ẩn, sau đó gửi biểu mẫu. – Jeff

10

Tôi sẽ cung cấp cho bạn cách nhanh chóng và bẩn để lấy dữ liệu. Trước tiên, bạn có thể sử dụng Fiddler2 http://www.fiddler2.com/fiddler2/ để kiểm tra POST mà trình duyệt của bạn gửi. Điều này dẫn đến POST sau:

POST http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX HTTP/1.1 
Host: www.invescopowershares.com 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip, deflate 
DNT: 1 
Connection: keep-alive 
Referer: http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 70669 

__EVENTTARGET=ctl00%24MainPageLeft%24MainPageContent%24ExportHoldings1%24LinkButton1&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUKLTE1OTcxNjYzNw9kFgJmD2QWBAIDD2QWBAIDD2QWCAIBDw9kFgQeC2........ 

Vì vậy, chúng ta có thể thấy 3 thông số đang được đăng là __EVENTTARGET, __EVENTVALIDATION và __VIEWSTATE.

Hình thức cần thiết cho cuộc gọi postForm sẽ là:

postForm(ftarget, "form name" = "aspnetForm", "method" = "POST", "action" = "holdings.aspx?ticker=PGX", "id" = "aspnetForm","__EVENTTARGET"=event.target,"__EVENTVALIDATION"=event.val,"__VIEWSTATE"=view.state) 

Bây giờ đến các bit nhanh chóng và dơ bẩn.Tôi sẽ chỉ cần mở trình duyệt và nhận các thông số có liên quan mà nó nhận được như sau:

library(rcom) 
ie = comCreateObject('InternetExplorer.Application') 
ie[["visible"]]=T # true for debugging 
ie$Navigate2("http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX") 
while(comGetProperty(ie,"busy")||comGetProperty(ie,"ReadyState")<4){ 
Sys.sleep(1) 
print(comGetProperty(ie,"ReadyState")) 
} 
myDoc<-comGetProperty(ie,"Document") 
myPW<-comGetProperty(myDoc,"parentWindow") 
comInvoke(myPW,"execScript","var dumVar1=theForm.__EVENTVALIDATION.value;var dumVar2=theForm.__VIEWSTATE.value;","JavaScript") 
event.val<-myPW[["dumVar1"]] 
view.state<-myPW[["dumVar2"]] 
event.target<-"ctl00$MainPageLeft$MainPageContent$ExportHoldings1$LinkButton1" 
ie$Quit() 
ftarget<-"http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX" 
web.data<-postForm(ftarget, "form name" = "aspnetForm", "method" = "POST", "action" = "holdings.aspx?ticker=PGX", "id" = "aspnetForm","__EVENTTARGET"=event.target,"__EVENTVALIDATION"=event.val,"__VIEWSTATE"=view.state) 
write(web.data[1],'temp.csv') 
fin.data<-read.csv('temp.csv') 


> fin.data[1,] 
    ticker SecurityNum      Name CouponRate maturitydate 
1 PGX 949746879 WELLS FARGO & COMPANY PFD  0.08    
    rating Shares PercentageOfFund PositionDate 
1 BBB+/Baa3 2538656  0.04442112 06/11/2012 

__EVENTVALIDATION, __VIEWSTATE có lẽ là luôn luôn giống nhau hoặc họ có lẽ cookie phiên. Bạn có thể có thể nhận được chúng bằng cách sử dụng RCurl nhưng như tôi nói đây là giải pháp nhanh chóng và bẩn và chúng tôi chỉ cần lấy những người mà Internet Explorer được đưa ra. Những điều cần lưu ý:

1). Điều này yêu cầu các cửa sổ có cài đặt IE để sử dụng các bit rcom.

2). Nếu bạn đang chạy ie9, bạn có thể cần phải thêm invescopowershares.com vào Cài đặt Chế độ xem Tương thích (vì microsoft dường như đã chặn sự kiện.val < -myPW [["dumVar1"]] nhập cuộc gọi com)

EDIT (CẬP NHẬT)

Sau khi xem xét trang web chi tiết hơn __EVENTVALIDATION, __VIEWSTATE đang được đặt làm biến javascript trên trang ban đầu. Chúng tôi chỉ có thể phân tích cú pháp này theo cách nhanh chóng và bẩn thỉu như sau mà không cần phải gọi đến trình duyệt.

dum<-getURL("http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX") 
event.target<-"ctl00$MainPageLeft$MainPageContent$ExportHoldings1$LinkButton1" 
event.val<-unlist(strsplit(dum,"__EVENTVALIDATION\" value=\""))[2] 
event.val<-unlist(strsplit(event.val,"\" />\r\n\r\n<script"))[1] 
view.state<-unlist(strsplit(dum,"id=\"__VIEWSTATE\" value=\""))[2] 
view.state<-unlist(strsplit(view.state,"\" />\r\n\r\n\r\n<script"))[1] 
ftarget<-"http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX" 
web.data<-postForm(ftarget, "form name" = "aspnetForm", "method" = "POST", "action" = "holdings.aspx?ticker=PGX", "id" = "aspnetForm","__EVENTTARGET"=event.target,"__EVENTVALIDATION"=event.val,"__VIEWSTATE"=view.state) 
write(web.data[1],'temp.csv') 
fin.data<-read.csv('temp.csv') 

Nền tảng trên nên hoạt động trên nền tảng.

+0

Bravo! Bravo! Cảm ơn nhiều! – GSee

1

Hiện tại, một chức năng trong số qmao package sẽ thực hiện việc này cho bạn. (Nó được dựa trên mã từ một câu trả lời đã được xóa cho câu hỏi này.)

Bạn có thể sử dụng dlPowerShares chức năng như thế này:

require("qmao") 
Symbol <- "PGX" 
dat <- qmao:::dlPowerShares(event.target = "ctl00$MainPageLeft$MainPageContent$ExportHoldings1$LinkButton1", 
          action = paste0("holdings.aspx?ticker=", Symbol)) 
> head(dat) 
    ticker SecurityNum       Name CouponRate maturitydate rating Shares PercentageOfFund PositionDate 
1 PGX 173080201   CITIGROUP CAPITAL XIII 0.07875 10/30/2040 BB/Ba2 2998647  0.04274939 08/31/2012 
2 PGX 949746879  WELLS FARGO & COMPANY PFD 0.08000    BBB+/Baa3 2549992  0.03935854 08/31/2012 
3 PGX 06739H362  BARCLAYS BK PLC    0.08125    A-/Baa3 2757635  0.03644835 08/31/2012 
4 PGX 46625H621  JPMORGAN CHASE    0.08625    BBB+/Baa1 2416021  0.03310707 08/31/2012 
5 PGX 060505765 BANK OF AMERICA CORP PFD 8.2 0.08200     BB+/B1 2345508  0.03128002 08/31/2012 
6 PGX 060505559 BANC OF AMERICA CORP PFD 8.625 0.08625     BB+/B1 2259484  0.03001599 08/31/2012 

Trong đoạn mã trên, event.target là chuỗi đầu tiên bên trong javascript: __ doPostBack() chức năng mà bạn sẽ nhận được khi bạn nhấp chuột phải vào liên kết “Tải xuống” và “Sao chép địa chỉ liên kết”.

action là phần dành riêng cho sản phẩm của url hành động.

Bên trong, các mã sau Jeff's gợi ý trong mình answer và tìm kiếm các nguồn của trang cho các giá trị các lĩnh vực cho "aspnetForm". Sau đó sử dụng những giá trị trong một cuộc gọi đến postForm (từ gói RCurl.)

Trong qmao package, dlPowerShares là sử dụng bởi getHoldings.powershares. Ngoài ra, getHoldings sẽ gọi getHoldings.powershares nếu một trong số Symbols được chuyển cho nó là biểu tượng của một ETF PowerShares.


p.s. nếu qmao:::dlPowerShares được gọi với mặc định của nó, nó sẽ tải xuống danh sách sản phẩm PowerShares từ http://www.invescopowershares.com/products/

Các vấn đề liên quan