嗯,你好。使用PyQT刮刀下載「變相」文件
我很難用PyQT抓取一個網站。事情是,該網站使用JSF,並且這個URL中的所有內容都是相同的。在這個例子中,我們使用「http://somesi.te/searchData.jsf」。
我打開它,填寫表單(目標是相同的URL),提交,並在同一頁面中獲得結果。直到那裏我的腳本工作正常。
但是,結果會返回爲1000頁分頁,並且底部有一個錨標記可用於下載一個Excel文件,並將所有結果放在一個文件中。 這個錨#靶向性,與onClick事件調用鑽嘴魚科功能,jsfcljs:
<a href="#" onclick="mojarra.jsfcljs(document.getElementById('formX'),{'formX:j_idt999':'formX:j_idt999'},'');return false">
分析功能,它只是在追加的形式<input type="hidden">
,並再次提交它,想必服務器理解它並將Excel文件而不是網頁發送給我。
問題是:服務器返回文件「僞裝」作爲網頁。 URL仍然是「somesi.te/searchData.jsf」,並且瀏覽器由於標題而將其識別爲文件。
而當我嘗試使用unsupportedContent()獲取文件時,它似乎不遵循流,它只是嘗試獲取在unsupportedContent信號中收到的URL。作爲當前URL「somesi.te/searchData.jsf」,當我保存文件時,我得到了頁面的源代碼,而不是獲取我的文件。
這是我現在使用的代碼:
def getTicketDetails(self):
self.webView.loadFinished.disconnect(self.getTicketDetails)
self.webView.page().setForwardUnsupportedContent(True)
self.webView.page().unsupportedContent.connect(self.downloadExcel)
downloadButton = documentElement.findFirst('input[id="force_download"]')
downloadButton.evaluateJavaScript("this.click();")
def downloadExcel(self, reply):
self.manager = self.webView.page().networkAccessManager()
self.manager.finished.connect(self.saveExcel)
postData = QByteArray()
postData.append("formX=formX&")
postData.append("formX:idSelecao_input=1&")
postData.append("formX:dataJanela_input=03/11/2015&")
postData.append("formX:dataAte_input=07/11/2015&")
postData.append("formX:j_idt106_input=all&")
postData.append("formX:j_idt120_input=0&")
postData.append("formX:produto_input=VLR&")
postData.append("formX:options=1&")
postData.append("formX:j_idt133_input=0&")
#postData.append("javax.faces.ViewState=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&")
postData.append("formX:j_idt999=formCI:j_idt999")
self.request = reply.request()
#self.reply = self.manager.get(self.request)
self.reply = self.manager.post(reply.request(), postData)
def saveExcel(self):
f = open('C:\\path\\to\\file\\searchResults.xls', 'wb')
f.write(str(self.reply.readAll()))
f.flush()
f.close()
self.exit()
到該文件的路徑是改變了這裏的目的。
我嘗試使用post方法以及get方法(評論上面的代碼片段),但他們都沒有工作,我總是最終得到一個損壞的xls文件,它是一個真正的HTML文件,源代碼爲這一頁。
當我取消註釋postData項「javax.faces.ViewState」時,服務器返回一個錯誤。我猜這裏是缺少的關鍵,因爲這個特定行上的特殊字符。
你知道我在做什麼錯嗎?我知道我用python的方式,但我根本不是專家。
如果有任何需要澄清,請讓我知道。
我目前使用python 2.7.9和PyQT 4.8.7。
你能提供一個真實網站的鏈接嗎?我希望看到提交表單所產生的確切請求。 –
此外,'javax.faces.ViewState' [可能](http://www.beyondjava.net/blog/jsf-viewstate-and-csrf-hacker-attacks/)既包含CSRF(預防)令牌,也包含一些狀態,這就是爲什麼服務器沒有它拒絕請求。 –
對不起,我無法提供實際的鏈接,因爲它是我的客戶之一的內部系統。 我的確做到了,它是特殊字符。我真的需要ViewState,但其上的「+」,「/」和「=」符號正在崩潰。 在Firefox上進行調試時,發現發送時,實際數據上的特殊字符被HTML十六進制代碼替代(即:%2A,%3D)。 當更換這些並再次發送時,它的工作非常出色。 –