2016年9月22日 星期四

超簡單爬蟲教學-使用R軟體的rvest套件抓網站資料(問題及進階篇)

這篇介紹爬蟲時可能碰到的問題
1.爬網頁時出現Error in open.connection(x, "rb") :  Failure when receiving data from the peer
2.如果想要一次爬很多頁的資訊怎麼做?
3.想爬其他除了網址外 attr屬性的網頁資訊
---------------------------------------------------------------------------------

1.爬網頁時出現Error in open.connection(x, "rb") :  Failure when receiving data from the peer
此時只要使用先把網頁下載的方法就可以解決了,這裡以爬mobile01的智慧型手機討論區標題為例,用前一篇的直接爬蟲方法會出現錯誤。







#爬mobile01的智慧型手機綜合討論區出現以下錯誤
read_html("http://www.mobile01.com/topiclist.php?f=61") %>% html_nodes("topic_gen") %>% html_text() %>% iconv("UTF-8")
Error in open.connection(x, "rb") : 
  Failure when receiving data from the peer
使用download.file()這個函數先下載網頁再爬蟲

download.file("http://www.mobile01.com/topiclist.php?f=61","D:/smartphone.html")
#此函數第一個參數輸入你想爬的網頁,第二個參數輸入你要下載此網頁到你電腦的路徑及檔名和檔案格式

trying URL 'http://www.mobile01.com/topiclist.php?f=61'
Content type 'text/html; charset=utf-8' length unknown
downloaded 52 KB
#輸入完出現這個表示下載成功

read_html("D:/smartphone.html") #之後爬網頁再輸入你剛剛下載的路徑到read_html裡面就可以成功爬此網頁了

2.
爬蟲就是要爬很多頁,不然手動複製就好啦!
所以我們可以善用for迴圈一次爬很多頁的資訊。
以剛剛的mobile01智慧型手機討論區為例,若我想要一次爬20頁的每篇標題怎麼做?

先下載20頁的mobile01網頁到電腦


for (i in 1:20){
loc=paste("http://www.mobile01.com/topiclist.php?f=61&p=",i,sep="")

#觀察到Mobile01討論區的網址,第一頁和第二頁只有最後面的p=1和=2的差別,所以使用paste()函數
#搭配for迴圈來產生第1到第20頁的網址。paste是個連接字串的函數,
#最後一個參數sep設定不要有空格就可以讓前面所有參數裡的字串連在一起,
#網路上有其他人的字串相關函數詳細教學,我會附在下面。

des=paste("D:/smart",i,".html",sep="")  #產生20個網頁的路徑和檔名。
download.file(loc,des)            #for每次會下載網頁從i=1~i=20
Sys.sleep(runif(1,2,5))           
# 若下載太多頁需要讓每次迴圈休息幾秒,不然網站會偵測到你讓伺服器負荷太大不讓你下載網頁。
}
爬取下載後的20個網頁文章討論標題,使用for迴圈及paste函數就可以爬取20頁的討論文章標題了。
smarttitle=NULL
for(i in 1:20){
  pathfile=paste("D:/smart",i,".html",sep="")  #產生讀取網頁檔案的路徑
  mtitle=read_html(pathfile) %>%                  
html_nodes(".topic_gen") %>%                   #用Selector選擇抓標題後得到的程式碼
  html_text() %>%  iconv("UTF-8")               #抓文字
smarttitle=c(smarttitle,mtitle)        #將每次for迴圈產的一頁的標題儲存到smarttitile
}
smarttitle =data.frame(smarttitle)    #儲存成表格
來看爬的結果,每頁有30篇討論,所以總共爬下600個文章標題囉!
當然還有更進階的爬蟲,附在後面的連結。

3.想爬mobile01標題上面有個浮標顯示人氣,沒辦法直接用Selector選擇,要怎麼做呢?




這時需要按ctrl+u去看網頁原始碼,接著ctrl+f搜尋127811找到這段程式碼。
可以看到第一行的接近尾端位置有href,後面括弧是這文章的網址,接著往下行看到我們要的人氣寫在title後面,其實這幾個就是html的網頁屬性啦,所以這跟上篇提到的抓網址方法幾乎是一樣的,所以你只要把本來的html_attr("href")改成html_("title")就可以抓到人氣囉!
read_html("D:/smart1.html") %>%
 html_nodes(".topic_gen") %>%html_attr("title")

[1] "人氣: 22"     "人氣: 671"    "人氣: 473"    "人氣: 330"    "人氣: 913"    "人氣: 451"   
 [7] "人氣: 462"    "人氣: 352"    "人氣: 550"    "人氣: 429"    "人氣: 1331"   "人氣: 748"   
[13] "人氣: 1100"   "人氣: 253"    "人氣: 649"    "人氣: 127690" "人氣: 1122"   "人氣: 572"   
[19] "人氣: 704"    "人氣: 1111"   "人氣: 7249"   "人氣: 4400"   "人氣: 781"    "人氣: 2596"  
[25] "人氣: 1551"   "人氣: 880"    "人氣: 1738"   "人氣: 1727"   "人氣: 3696"   "人氣: 330" 
抓到人氣後,可以使用substr()函數把數字的部分挑出來。
x="人氣: 1551"
substr(x,5,nchar(x))   
#第2個參數輸入想要的字串開始位置,第3個輸入想要字串結束的位置,
#使用nchar(x)計算字串長度,所以是都會挑到最後一個

[1] "1551"     #結果
--------------------------------------------------------------------------------------------------------------------------

 若不太了解rvest套件怎麼用,可以先參考
超簡單爬蟲教學-使用R軟體的rvest套件抓網站資料(基礎篇)


 爬到想要的資訊之後再整理一下,就可以做很多分析,其中一個是做文字探勘,有別人做的教學也附在下面連結。

若有問題或建議,歡迎留言交流喔!!




參考資料:

進階的使用rvest爬Indeed職缺內容(英文)
http://stat4701.github.io/edav/2015/04/02/rvest_tutorial/


R字串相關函數教學
https://www.ptt.cc/bbs/Statistics/M.1277714037.A.2CC.html
http://molecular-service-science.com/2015/01/18/text-processing-in-r-using-grep/

文字探勘相關教學
http://rstudio-pubs-static.s3.amazonaws.com/12422_b2b48bb2da7942acaca5ace45bd8c60c.html
http://www.slideshare.net/tw_dsconf/r-64232974
https://cran.r-project.org/web/packages/text2vec/vignettes/text-vectorization.html










5 則留言:

  1. 想請教您知道如何在 r 上使用 proxy 嗎 ? 畢竟大量的 download.file() 應該很有可能被鎖 ?

    回覆刪除
    回覆
    1. 你好呀,抱歉晚回了。
      關於這問題,如果是要大量下載,我是每個for迴圈都搭配
      Sys.sleep()讓系統暫時休息的函數,就不會被鎖,
      我當時一次總共可以爬150頁的網頁內容,供您參考。

      如果真的需要proxy去爬,
      https://goo.gl/GkPuKk
      https://support.rstudio.com/hc/en-us/articles/200488488-Configuring-R-to-Use-an-HTTP-or-HTTPS-Proxy
      有更多資訊參考
      謝謝提問交流

      刪除
  2. 想請教您在Starting off simple: Scraping The Lego Movie on imdb這篇文章中,html_nodes("strong span") %>%裡的strong span是從哪裡得知的呢?因為我用selectorgadget得出來的是.imdbRating,謝謝。

    回覆刪除
  3. 請問一下,我出現以下的error應該如何改善處理呢?

    嘗試 URL 'https://www.basketball-reference.com/teams/i/2017_games.html1'
    Error in download.file(loc, des) :
    無法開啟 URL 'https://www.basketball-reference.com/teams/i/2017_games.html1'
    此外: Warning message:
    In download.file(loc, des) :
    cannot open URL 'https://www.basketball-reference.com/teams/i/2017_games.html1': HTTP status was '404 Not Found'

    回覆刪除
  4. 我想請問一下 我爬了某一個網站後發現要翻頁的時候連線就自動斷開了,請問這是什麼問題呢?
    無法開啟 URL 'https://www.backpackers.com.tw/forum/forumdisplay.php?f=263&order=desc&page2'
    此外: Warning message:
    In download.file(loc, des) : InternetOpenUrl 失敗: '無法建立與伺服器的連線'

    回覆刪除