您好,登錄后才能下訂單哦!
如何模擬HTTP請求實現(xiàn)網(wǎng)頁自動操作和數(shù)據(jù)采集?針對這個問題,今天小編總結這篇代碼與解析相結合的文章,希望大家根據(jù)這篇文章可以有所收獲。
前言
網(wǎng)頁可分為信息提供和業(yè)務操作類,信息提供如新聞、股票行情之類的網(wǎng)站。業(yè)務操作如網(wǎng)上營業(yè)廳、OA之類的。當然,也有很多網(wǎng)站同時具有這兩種性質,像微博、豆瓣、淘寶這類網(wǎng)站,既提供信息,也實現(xiàn)某些業(yè)務。
普通上網(wǎng)方式一般都是手動操作(這個不需要解釋:D)。但有時候人工手動操作的方式可能就無法勝任了,如爬取網(wǎng)絡上大量數(shù)據(jù),實時監(jiān)測某個頁面的變化,批量操作業(yè)務(如批量發(fā)微博,批量淘寶購物)、刷單等。由于操作量大,而且都是重復的操作,人工操作效率低下,且易出錯。這時候就可以使用軟件來自動操作了。
本人開發(fā)過多個這類軟件,有網(wǎng)絡爬蟲、自動批量操作業(yè)務這類的。其中使用到的一個核心功能就是模擬HTTP請求。當然,有時會使用HTTPS協(xié)議,而且網(wǎng)站一般需要登陸后才能進一步操作,還有最重要的一點就是弄清楚網(wǎng)站的業(yè)務流程,即知道為了實現(xiàn)某個操作該在什么時候向哪個頁面以什么方式提交什么數(shù)據(jù),最后,要提取數(shù)據(jù)或知道操作結果,就還需要解析HTML。本文將一一闡述。
本文使用C#語言來展示代碼,當然也可以用其它語言實現(xiàn),原理是一樣的。以登陸京東為實例。
模擬HTTP請求
C#模擬HTTP請求需要使用到如下類:
?WebRequest
?HttpWebRequest
?HttpWebResponse
?Stream
先創(chuàng)建一個請求對象(HttpWebRequest),設置相關的Headers信息后發(fā)送請求(如果是POST,還要把表單數(shù)據(jù)寫入網(wǎng)絡流),如果目標地址可訪問,會得到一個響應對象(HttpWebResponse),從相應對象的網(wǎng)絡流中就可讀出返回結果。
示例代碼如下:
String contentType = "application/x-www-form-urlencoded"; String accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*"; String userAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36"; public String Get(String url, String encode = DEFAULT_ENCODE) { HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; InitHttpWebRequestHeaders(request); request.Method = "GET"; var html = ReadHtml(request, encode); return html; } public String Post(String url, String param, String encode = DEFAULT_ENCODE) { Encoding encoding = System.Text.Encoding.UTF8; byte[] data = encoding.GetBytes(param); HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; InitHttpWebRequestHeaders(request); request.Method = "POST"; request.ContentLength = data.Length; var outstream = request.GetRequestStream(); outstream.Write(data, 0, data.Length); var html = ReadHtml(request, encode); return html; } private void InitHttpWebRequestHeaders(HttpWebRequest request) { request.ContentType = contentType; request.Accept = accept; request.UserAgent = userAgent; } private String ReadHtml(HttpWebRequest request, String encode) { HttpWebResponse response = request.GetResponse() as HttpWebResponse; Stream stream = response.GetResponseStream(); StreamReader reader = new StreamReader(stream, Encoding.GetEncoding(encode)); String content = reader.ReadToEnd(); reader.Close(); stream.Close(); return content; }
可以看出,Get和Post方法的代碼大部分都相似,所以代碼進行了封裝,提取了相同代碼作為新的函數(shù)。
HTTPS請求
當網(wǎng)站使用https協(xié)議時,以上代碼就可能會出現(xiàn)以下錯誤:
The underlying connection was closed: Could not establish trust relationship for
原因是證書錯誤,用瀏覽器打開會出現(xiàn)如下頁面:
當點擊繼續(xù)前往xxx.xx(不安全)時,就可繼續(xù)打開網(wǎng)頁。在程序中,也只要模擬這一步就可以繼續(xù)了。C#中只需設置ServicePointManager.ServerCertificateValidationCallback代理,在代理方法中直接返回true就行了。
private HttpWebRequest CreateHttpWebRequest(String url) { HttpWebRequest request; if (IsHttpsProtocol(url)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); request = WebRequest.Create(url) as HttpWebRequest; request.ProtocolVersion = HttpVersion.Version10; } else { request = WebRequest.Create(url) as HttpWebRequest; } return request; } private HttpWebRequest CreateHttpWebRequest(String url) { HttpWebRequest request; if (IsHttpsProtocol(url)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); request = WebRequest.Create(url) as HttpWebRequest; request.ProtocolVersion = HttpVersion.Version10; } else { request = WebRequest.Create(url) as HttpWebRequest; } return request; }
這樣,就可正常訪問https網(wǎng)站了。
記錄Cookies實現(xiàn)身份認證
有些網(wǎng)站需要登錄才能執(zhí)行下一步操作,比如在京東購物需要先登錄。網(wǎng)站服務器使用session來記錄客戶端用戶,每一個session對應一個用戶,而前面的代碼每次創(chuàng)建一個請求都會重新建立一個session。即使登錄成功,在執(zhí)行下一步操作由于新創(chuàng)建了一個連接,登錄也是無效的。這時就得想辦法讓服務器認為這一系列的請求來自同一個session。
客戶端只有Cookies,為了在下次請求的時候讓服務器知道該客戶端對應哪個session,Cookies中會有一個記錄session ID的記錄。所以,只要Cookies相同,對服務器來說就是同一個用戶。
這時需要使用到CookieContainer,顧名思義,這就是一個Cookies容器。HttpWebRequest有一個CookieContainer屬性。只要把每次請求的Cookies都記錄在CookieContainer,下次請求時設置HttpWebRequest的CookieContainer屬性,由于Cookies相同,對于服務器來說就是同一個用戶了。
public String Get(String url, String encode = DEFAULT_ENCODE) { HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; InitHttpWebRequestHeaders(request); request.Method = "GET"; request.CookieContainer = cookieContainer; HttpWebResponse response = request.GetResponse() as HttpWebResponse; foreach (Cookie c in response.Cookies) { cookieContainer.Add(c); } }
分析調試網(wǎng)站
以上就實現(xiàn)了模擬HTTP請求,當然,最重要的還是分析站。一般的情況都是沒有文檔、找不到網(wǎng)站開發(fā)人員,從一個黑盒子開始探索。分析工具有很多,推薦使用Chrome+插件Advanced Rest Client,Chrome的開發(fā)者工具能讓我們知道打開一個網(wǎng)頁時后臺做了哪些操作與請求,Advanced Rest Client可模擬發(fā)送請求。
比如在登錄京東時,會提交如下數(shù)據(jù):
我們還能看到京東的密碼居然是明文傳輸,安全性很讓人擔心??!
還能看到返回的數(shù)據(jù):
返回的是JSON數(shù)據(jù),不過\u8d26這些是什么?其實這是Unicode編碼,使用Unicode編碼轉換工具,即可轉換成可讀的文字,比如這次返回的結果是:賬戶名與密碼不匹配,請重新輸入。
解析HTML
HTTP請求獲得的數(shù)據(jù)一般是HTML格式,有時也可能是Json或XML。需要解析才能提取有用數(shù)據(jù)。解析HTML的組件有:
?HTML Parser。多個平臺可用,如Java/C#/Python。很久沒用了。
?HtmlAgilityPack。通過通過XPath來解析HMTL。
以上就是模擬HTTP請求實現(xiàn)網(wǎng)頁自動操作和數(shù)據(jù)采集的具體操作,代碼詳細清楚,如果在日常工作遇到這個問題,希望你能通過這篇文章解決問題。如果想了解更多相關內容,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。