打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
掌控POST(5)
 本帖最後由 michael3636 於 2015-5-1 20:00 編輯

Part 5







老規矩,來點知識普及:

字符編碼: 啥是編碼?為啥瀏覽器從來不亂碼,我用XHR老會碰到亂碼?讓我們解開這個秘密吧

什麼決定了網頁的編碼?2個地方


  • 一個服務器返回頭部裡的」Conten-type」,如果裡面有"CharSet"鍵,瀏覽器就根據這個鍵指定的值去設置網頁編碼
  • 如果1里面沒有"CharSet",瀏覽器就去網頁源代碼找charset相關的值,大家可以右鍵查看源文件,去搜索這個關鍵字,一般都在網頁開頭的地方,這裡設定了網頁的編碼,瀏覽器根據這裡的設定設定網頁的編碼

以下為本帖隱藏內容

==============================

XHR呢?它只管1,不管2,也就是說,1里指定了,,它就能正確編碼字符串,1里不指定,它鐵定亂碼,以前默認是」utf-8」,就算1里不指定它就默認用這個編碼,現在連默認都省了.直接給你亂碼看

==============================

通過查看源文件,我們能知道,按鍵和新浪都是」GBK」編碼的,為啥用xhr去玩,一個是亂碼一個是正常的呢?

代碼說話:

  1. //看按鍵
  2. Set http = CreateObject("WinHttp.WinHttpRequest.5.1")//創建XHR對象
  3. URL = "http://bbs.anjian.com/forum.php?mod=forumdisplay&fid=17"//按鍵論壇
  4. http.open "GET", URL, False
  5. http.send
  6. If Not isEmpty(http.responsetext) Then
  7. MessageBox http.getresponseheader("content-type") //看看content-type內容
  8. Else MessageBox "失敗"
  9. End If
  10. //看新浪
  11. URL = "http://www.sina.com.cn" //看新浪
  12. http.open "GET", URL, False
  13. http.send
  14. If Not isEmpty(http.responsetext) Then
  15. MessageBox http.getresponseheader("content-type") //看看content-type內容
  16. Else MessageBox "失敗"
  17. End If
複製代碼

明白了吧…只要服務器表頭裡的」Conten-type」設置了編碼,XHR就能正常工作啦,,,如果不指定,亂碼啦..那有人會說了,我在Part 3 裡的獲取」網頁源文件」哪個函數完全是可以一個參數的搞定的,只要在返回的源文件裡查下」charset」對應的編碼,函數豈不是可以自動正確編碼了麼?沒錯,你說的是沒錯,但是我是不推薦的,要知道源文件是很大的,成千上萬個字符,這樣的字符串操作是很慢的,為了省個參數放棄效率,我個人不削為之,但是去」content-type」檢查下我是很樂意的,(畢竟很短的字符串),有」charset」的就不根據參數2轉碼直接輸出,沒有的根據參數轉碼!!!!!

當然,這僅僅是我個人的偏好,大家不喜歡可以去改嘛!!!

符合我個人口味的高效率"獲得網頁源文件"函數
  1. Function 獲得網頁源文件(網頁地址,網頁編碼) //多個參數.設置編碼.跟亂碼說88
  2. Dim xmlHttp, xmlUrl,ObjStream
  3. If InStr(網頁地址, "http://") = 0 Then
  4. xmlUrl = "http://" & 網頁地址
  5. Else
  6. xmlUrl = 網頁地址
  7. End if
  8. Set xmlHttp = CreateObject("WinHttp.WinHttpRequest.5.1") //用這個對象,跟緩存/cookie 干擾說88
  9. xmlHttp.Open "GET", xmlUrl, True
  10. xmlHttp.Send
  11. If xmlhttp.waitforresponse() Then
  12. If instr(1,xmlhttp.getresponseheader("content-type"), "charset",1) Then //通過判斷"content-type"是否有"charset"字符串來決定是否根據參數2轉碼
  13. 獲得網頁源文件 = xmlHttp.ResponseText
  14. Exit Function
  15. Else
  16. Set ObjStream = CreateObject("Adodb.Stream")
  17. ObjStream.Type = 1
  18. ObjStream.Mode = 3
  19. ObjStream.Open
  20. ObjStream.Write xmlHttp.ResponseBody
  21. ObjStream.Position = 0
  22. ObjStream.Type = 2
  23. ObjStream.Charset = 網頁編碼
  24. 獲得網頁源文件 = ObjStream.ReadText
  25. End If
  26. Else
  27. 獲得網頁源文件=False //如果獲取失敗返回值是false
  28. End If
  29. End Function
複製代碼


瞭解了XHR的工作編碼機制,我們現在要說的是將是我們在玩XHR的時候需要切實掌握的編碼知識:

我們需要處理的編碼分2部分

  • 我們從服務器收到的字符的編碼: 也就是源文件的編碼,這個在上面和Part 3 裡講的很詳細了
  • 我們發給服務器的字符的編碼: 我們發給服務器的東西無非就是 2個部分,URL和我們發送的內容需要處理編碼問題


  • URL的編碼問題
當我們的URL裡帶查詢語句的時候(就是網頁地址裡有"?","?"後面的就是查詢參數),而這個查詢字符是中文(或其他非英文語言)的時候,我們不得不面對這些字符的編碼問題,就跟 Part 4 裡的問題:如果我們要用"GET"方式登錄我們的中文賬號腫麼辦? 這勢必讓我們面臨url裡帶這中文這個問題,直接提交是肯定登錄不上的,讓我們通過學習解決這個問題吧
先大體說下ulr的規則,url的建議規則是,凡是中文這樣的非asc字符,必須編碼,編碼的形式是:類似 %2位數字%2位數字等等
比如"按鍵"這2個字:根據url建議規則,它應該是這樣的:
%E6%8C%89%E9%94%AE (utf-8的編碼),或者
%B0%B4%BC%FC (gbk/gb2312編碼)
很明顯.按鍵論壇是gbk編碼的.後者才是適合我們的編碼,後者加在url裡才會正確,是的的確是這樣
一個好消息是:其實就URL而言,很多大家都並不是很遵守,很多網站都可以直接提交字符,而不需要進過編碼加工,比如,按鍵,百度,淘寶等等等等,我們只要發送符合網頁編碼的字符就行了,而不需要轉成"%"這種形式,就按鍵而言,我們只要把XHR對象的某個屬性設置成936就行了如下(詳見Part 3):
http.[option](2)=936

url的問題就解決啦..現在你可定堂而皇之的用"GET"方法登陸你的中文賬號啦


  • "
    OST"方式發送的內容編碼

post是可以帶著內容向URL地址提交數據的,它的內容編碼腫麼辦,很遺憾的告訴大家,除了豐衣足食自己動手,沒有其他辦法
8過麼,能解決就好還沒寫完啊..咋就發出來了..我點的保存啊.....不是發佈啊......啊啊啊啊啊啊

好咯,進入今天的主題:

如何從又長又亂糟糟的源文件字符串裡得到我們需要的信息?

設定個目標:
我們要從按鍵論壇=>綜合版塊第一頁取得所有的帖子標題,作者,發佈日期,並且得到進入對應帖子的關鍵數據

3個方法


  • 用字符串處理函數

這個麼…俺有火槍了,鐵定不會用板磚,打死你我也不會用這個方法,據說有的」大神」會去用,我只能呵呵了

2. 用無所不能的正則

極力推薦.高效又方便,看代碼:

分析:大家看圖1,這是其中一個普通帖子(非置頂帖)在源文件裡的字段,我們用正則把我們需要的提取出來,上代碼!!!

  1. Set http = CreateObject("WinHttp.WinHttpRequest.5.1")//創建XHR對象
  2. URL = "http://bbs.anjian.com/forum.php?mod=forumdisplay&fid=17"//按鍵論壇
  3. http.open "GET", URL, True
  4. http.send
  5. If http.waitforresponse() Then
  6. text= http.responsetext //為了方便大家看代碼,把返回的文本賦值給text變量
  7. Else MessageBox "失敗"
  8. End If
  9. //開始處理返回的源文件字符串,正則
  10. Set re = New regexp
  11. re.[global] = true
  12. re.IgnoreCase = True
  13. //下面就是提取指定信息的正則表達式
  14. re.pattern = "<tbody id=""normalthread_(\d*)""[\s\S]+?class=""xst"" >([^<]*)<[\s\S]*?c=""1"">([^<]*)<[\s\S]*?>(\d{4}-\d{1,2}-\d{1,2})"
  15. Set matches = re.execute(text)
  16. For Each match In matches
  17. TracePrint match.submatches(1) & " : " & match.submatches(2) & " : " & match.submatches(3)//調試輸出信息看看
  18. TracePrint "帖子的關鍵數據:" & match.submatches(0)
  19. Next
複製代碼
呵呵呵..正則真好!!!


3.用HTML DOM 去玩,喜歡玩IE對象的夥伴們高興了.關於html Dom, 又是個超大話題.不展開,會的就用,不會我也米辦法,代碼如下:
  1. Set http = CreateObject("WinHttp.WinHttpRequest.5.1")//創建XHR對象
  2. URL = "http://bbs.anjian.com/forum.php?mod=forumdisplay&fid=17"//按鍵論壇
  3. http.open "GET", URL, True
  4. http.send
  5. If http.waitforresponse() Then
  6. text= http.responsetext //為了方便大家看代碼,把返回的源文件文本賦值給text變量
  7. Else MessageBox "失敗"
  8. End If

  9. //開始處理返回的源文件字符串.html dom
  10. Set doc = CreateObject("htmlfile") //dom對象
  11. doc.designMode="on"
  12. doc.write text
  13. Set tbds = doc.getelementsbytagname("tbody")
  14. For Each tbd In tbds
  15. If instr(tbd.id,"normalthread") Then
  16. Set ass = tbd.getelementsbytagname("a")
  17. For Each a In ass
  18. If a.classname = "xst" Then
  19. Set b=a.parentnode.nextSibling
  20. TracePrint a.innertext & " " & b.innertext
  21. End If
  22. Next
  23. End if
  24. Next
複製代碼


好啦..在源文件裡提取我們需要的內容的方式介紹完了.這個怎麼說呢.會者不難難者不會,就理性建議而言,2/3兩種方法都可以,1就算了,具體哪種看你熟悉哪種吧,如果啥都不會,那就去學一種推薦學正則,不學的話.學XHR是沒有任何意義的. 
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
如何简单获取FLASH动画的URL地址
史上最详细的ajax教程(一),不容错过
JavaScript中的AJAX
ajax学习笔记
教你用迅雷下载百度云网盘的大文件
JS中对URL进行转码与解码
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服