簡體   English   中英

在 R 中使用 getURL() 抓取網頁時如何避免空字符?

[英]How to avoid null character when scraping a web page with getURL() in R?

使用RCurlgetURL()函數抓取網站時遇到問題。 例如,對於http://dogecoin.com,它返回一個錯誤,指出鏈中間有一個 NULL 字符(字面翻譯。

> x <- getURL("http://dogecoin.com/")
Error in curlPerform(curl = curl, .opts = opts, .encoding = .encoding) : 
  caractère nul au milieu de la chaîne : '\037\x8b\b\0\0\0\0\0\0\003\xed]\xebr\xdbF\x96\xfe\035=E\x9b\xa9\x89\xe4]\x82\xd4͗8\x92R\xb2|\x9d\x91-\x97\xa5\xac7\x95IiA\002$a\x81\0\x82\x8bhf2ﰯ\xb1\xaf\xb1\xfbb\xfb}\xa7\033WB\022E{\xa62\025\xa5*2I\xf4\xbdO\x9f\xcbw\xcei\xec\xdd{vrt\xf6\xe3\xbb\xe7j\x92N\xfd\x83\xb5\xbd\xfc\037\xd7v\016\xd6\024\xfeۻgY\xf2\xc1\xfcw~^\xf9\xb2\xf0\xf1\xdc\024=\xc7\177}\xd5\xc7_\xa5\xf8Y\xff\x91\xbf\xf2\x9fR\033\xe7\xf7\xf1\xaf.\xde\xc7\003\xa5\xe4\xef_\xe5\xef\177\xe1\xaf\xfe\x88V\xf4\xaf\xfa_)φ\xf1\177\xed/JI\177ů|\xae\xfaR\xfe\xaf\xe7\xe7\xdd\xf3>\xfe\xe21?+\xf9\\\xfe9Gs\xbabu\xa2ғ\xd4Y\x93\x9f\x93PM\xed\xf8"\x8bz\xeaҍ\xe7j\xe6\016\022/u{j\026\xcezR²\016\xd6־₩7nj\xcb\xf7\xaf\xf6R/\xf5݃g\xe1\xd8\035\x86^\xb0\xd7\xd7\xdf\xf1`\xca2É\035'n\xba\xdf\xc9ґ\xf5\xb8\xc3\n\xfa\xf70H\xdd\0\xbf\xe7\025\x95\x97(;Pa\xe4\006\030J\026\017]\025\xb9nl\xa5\xa1\xc5\177\x95㍽\xd4\xf6\xd50\x8bc7\030λjd_\x86\xb1\xeb\xa8\xc1\\\x9dN\xbc\x81\xad^\aY\x82\xd1

在極少數情況下,它會返回一個干凈的 HTML 代碼,但大多數時候我都會遇到此錯誤。 它似乎與他們的網站有關,正如你所看到的,有幾個奇怪的字符,比如 ₩ 和 4͗。

一種選擇是使用getURLcontent()下載原始數據,但隨后我無法將二進制內容轉換為 HTML。

我嘗試更改.encoding參數,但它沒有給出預期的結果。 我怎么能抓取這個網頁?

編輯:詳細模式

> getURL("http://dogecoin.com/", verbose = TRUE)
*   Trying 192.30.252.153...
* Connected to dogecoin.com (192.30.252.153) port 80 (#0)
> GET / HTTP/1.1
Host: dogecoin.com
Accept: */*

< HTTP/1.1 200 OK
< Server: GitHub.com
< Date: Wed, 25 Oct 2017 10:12:26 GMT
< Content-Type: text/html; charset=utf-8
< Transfer-Encoding: chunked
< Last-Modified: Tue, 16 May 2017 01:27:52 GMT
< Access-Control-Allow-Origin: *
< Expires: Wed, 25 Oct 2017 10:05:08 GMT
< Cache-Control: max-age=600
< Content-Encoding: gzip
< X-GitHub-Request-Id: A4D0:66A8:93356A1:D740FF7:59F0638A
< 
Error in curlPerform(curl = curl, .opts = opts, .encoding = .encoding) : 
  caractère nul au milieu de la chaîne : '\037\x8b\b\0\0\0\0\0\0\003\xed]\xebr\xdbF\x96\xfe\035=E\x9b\xa9\x89\xe4]\x82\xd4͗8\x92R\xb2|\x9d\x91-\x97\xa5\xac7\x95IiA\002$a\x81\0\x82\x8bhf2ﰯ\xb1\xaf\xb1\xfbb\xfb}\xa7\033WB\022E{\xa62\025\xa5*2I\xf4\xbdO\x9f\xcbw\xcei\xec\xdd{vrt\xf6\xe3\xbb\xe7j\x92N\xfd\x83\xb5\xbd\xfc\037\xd7v\016\xd6\024\xfeۻgY\xf2\xc1\xfcw~^\xf9\xb2\xf0\xf1\xdc\024=\xc7\177}\xd5\xc7_\xa5\xf8Y\xff\x91\xbf\xf2\x9fR\033\xe7\xf7\xf1\xaf.\xde\xc7\003\xa5\xe4\xef_\xe5\xef\177\xe1\xaf\xfe\x88V\xf4\xaf\xfa_)φ\xf1\177\xed/JI\177ů|\xae\xfaR\xfe\xaf\xe7\xe7\xdd\xf3>\xfe\xe21?+\xf9\\\xfe9Gs\xbabu\xa2ғ\xd4Y\x93\x9f\x93PM\xed\xf8"\x8bz\xeaҍ\xe7j\xe6\016\022/u{j\026\xcezR²\016\xd6־₩7nj\xcb\xf7\xaf\xf6R/\xf5݃g\xe1\xd8\035\x86^\xb0\xd7\xd7\xdf\xf1`\xca2É\035'n\xba\xdf\xc9ґ\xf5\xb8\xc3\n\xfa\xf70H\xdd\0\xbf\xe7\025\x95\x97(;Pa\xe4\006\030J\026\017]\025\xb9nl\xa5\xa1\xc5\177\x95㍽\xd4\xf6\xd50\x8bc7\030λjd_\x86\xb1\xeb\xa8\xc1\\\x9dN\xbc\x81\xad^\aY\x82\xd1
> 

RCurl::getURL()似乎既沒有檢測到Content-Encoding: gzip標頭,也沒有檢測到前兩個字節的“魔術”代碼,這也表明內容是 gzip 編碼的。

我會建議——正如邁克爾所做的那樣——出於我稍后會httr的原因而切換到httr ,但這將是一個更好的httr習語:

library(httr)

res <- GET("http://dogecoin.com/")
content(res)

content()函數提取原始響應並返回一個xml2對象,該對象類似於在使用RCurl::getURL()您可能會使用的XML庫解析對象。

另一種方法是向RCurl::getURL()添加一些拐杖:

html_text_res <- RCurl::getURL("http://dogecoin.com/", encoding="gzip")

在這里,我們明確地通知getURL()內容是 gzip 格式的,但是這充滿了危險,因為如果上游服務器決定使用,比如說,brotli 編碼,那么你會得到一個錯誤。

如果您仍然想使用RCurl與切換到httr我建議您為此站點執行以下操作:

RCurl::getURL("http://dogecoin.com/", 
              encoding = "gzip",
              httpheader = c(`Accept-Encoding` = "gzip"))

這里'給了getURL()解碼拐杖,但也明確告訴上游服務器 gzip 是 👍 並且它應該使用該編碼發送數據。

但是, httr將是更好的選擇,因為它和它使用的curl包以更徹底的方式處理 Web 服務器交互和內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM