[問題] 用R爬Instagram

看板R_Language作者 (文本能吃嗎)時間7年前 (2018/04/22 15:51), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
[問題類型]:使用R語言爬Instagram流程遇到問題 程式諮詢(我想用R 做某件事情,但是我遇到問題) [軟體熟悉度]: 入門(寫過其他程式,只是對語法不熟悉) [問題敘述]: 各位好 因為目前在學校修R相關的課教到爬蟲 爬一般的新聞網站、PTT、購物網站等的大概都可以了 最近想要嘗試爬爬看Instagram 最終目標是爬下特定hashtag以及特定帳戶的貼文 譬如說搜尋#植劇場 或是到金酒籃球隊(SBL的球隊公開帳號) 抓下貼文、按讚數、追蹤數等 最後再來看是否能夠做一些分析 現在嘗試過三種方法但都有遇到一定的問題 下方分別敘述 *方法一 使用instaR package 連結:https://github.com/pablobarbera/instaR 這個方法主要是利用instagram developer tool 連接官方的API 但因為instagram官方調整其政策 所以這個package裡面的一些function會被擋 像是searchInstagram() 函數爬 public content就失效了 在instagram developer tool 的 permission review處 (詳細步驟請參考 https://www.r-bloggers.com/analyze-instagram-with-r/) 若選擇自己的需求為 "I want to display hashtag content and public content on my website." Instagram 的解答是: "This use case is not supported. We do not approve the public_content permission for one-off projects such as displaying hashtag based content on your website. " 所以這個方法目前看來是不OK了 *方法二 使用RSelenium package 連結:https://github.com/ropensci/RSelenium 若需要操作教學的話可以參考 https://vectorf.github.io/2017/07/10/20170710-%E5%88%9D%E6%8E%A2RSelenium/ http://rpubs.com/bigbrotherchen/randseleniumpractice 我目前按照教學操作上沒有太大問題 小提醒一下開啟cmd輸入java...那串之後記得不要關掉cmd!!! 我的作法大致描述如下 # 載入package library(RSelenium) library(rvest) library(tidyverse) rm(list = ls()) options(stringsAsFactors = FALSE) username = "這串打你的IG帳號" # <username here> password = "這串打你的IG密碼" # <password here> hashtag = "#你要搜尋的hashtag" # <hashtag here> # 建立連線後開啟instagram登入網址 remDr <- remoteDriver(remoteServerAddr = "localhost", port = 4444, browserName = "chrome") remDr$open() remDr$navigate("https://www.instagram.com/accounts/login/") # 控制輸入帳號密碼後點選登入按鈕 webElem <- remDr$findElement(using = 'xpath', value = "//div/input[@name='username']") webElem$sendKeysToElement(list(username)) webElem2 <- remDr$findElement(using = 'xpath', value = "//div/input[@name='password']") webElem2$sendKeysToElement(list(password)) webElem3 <- remDr$findElement(using = 'xpath', value = "//span/button") webElem3$clickElement() # 在搜尋框裡面輸入hashtag後點選搜尋按鈕 webElem4 <- remDr$findElement(using = 'xpath', value = "//div/input[@placeholder='搜尋']") webElem4$sendKeysToElement(list(hashtag)) webElem5 <- remDr$findElement(using = 'xpath', value = "//*[@id='react-root']/section/nav/div[2]/div/div/div[2]/div[2]/div[2]/div/a[1]") webElem5$clickElement() #(到這邊的時候就已經進入特定hashtag的所有貼文頁面了 # 控制網頁自動拉到網頁最下方 last_height = 0 repeat { remDr$executeScript("window.scrollTo(0,document.body.scrollHeight);", list(remDr$findElement("css", "body"))) Sys.sleep(2) new_height = remDr$executeScript("return document.body.scrollHeight", list(remDr$findElement("css", "body"))) if(unlist(last_height) == unlist(new_height)) { break } else { last_height = new_height } } #到這邊的時候會拉到所有貼文最底下 #之所以會這樣做是因為請教朋友的時候對方說 #這類網站叫做waterfall 不會一次讀完 #跟FB有點像往下拉才讀的到 # 想要用rvest package一般爬網頁的作法 remDr$getPageSource()[[1]] %>% read_html(encoding = "UTF-8") #這邊就會遇到問題 #結果長這樣 #{xml_document} #<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-tw" class="js logged-in client-root"> #Error in nchar(desc) : invalid multibyte string, element 2 #上網查了一下Error in nchar(desc)跟invalid multibyte string #但問題主要是跟編碼有關所以才會加入UTF-8 #可是還是沒有效果 #想要請問一下是否有人知道 #因為我不太熟html跟xpath所以爬得有點辛苦 *方法三 使用jsonlite package # 載入package library(rvest) library(tidyverse) library(jsonlite) library(httr) library(xml2) #我先以#台啤18天 當作目標進去IG頁面 #其網址如下: #https://www.instagram.com/explore/tags/台啤18天/?hl=zh-tw #接下來我按照爬蟲教學常見的作法 #先按下檢查後點preserve log 還有clear(左上角紅點右邊的按鈕) #圖請參考: https://i.imgur.com/Pt6O5Gl.png
#接下來重新整理頁面後 #觀察XHR部分後發現?__a=1這個東西是要抓取的目標 # 用函數開始抓 url = "https://www.instagram.com/explore/tags/%E5%8F%B0%E5%95%A418%E5%A4%A9/?__a=1" res <- fromJSON(content(GET(url), "text")) #這部分res出來之後有自己要的資料 #譬如說抓下來某一則貼文的內容在下方的程式碼裡面可以找到 res$graphql$hashtag$edge_hashtag_to_media$edges$node$edge_media_to_caption$edges[[20]] #但這段程式碼裡面沒有包含所有的貼文僅有一部分而已 #所以往下拉之後繼續觀察XHR部分發現有一塊東西?query_hash是目標 #圖請參考 https://i.imgur.com/jUQLMtt.png
#試圖抓取其url之後利用函數但遇到問題了 url10 <- "https://www.instagram.com/graphql/query/?query_hash=ded47faa9a1aaded10161a2ff32abb6b&variables=%7B%22tag_name%22%3A%22%E5%8F%B0%E5%95%A418%E5%A4%A9%22%2C%22first%22%3A1%2C%22after%22%3A%22AQBs_yhQbCXYxR7WgT2L598zGjRAT1iunnUIPbNxMQx8BbxZsm-S3YMyJK4bCyBRntcrLemDJqF_b_5Y9YlnQvUS7Iz34M6dWu8ONoX9_jJVaw%22%7D" res10 <- fromJSON(content(GET(url10), "text")) #遇到的error顯示 #Error: parse error: premature EOF # # (right here) ------^ #這塊也有找答案但找不到處理方式 再補充一下 我還有參考其他作法 分別如下: https://www.diggernaut.com/blog/how-to-scrape-pages-infinite-scroll-extracting-data-from-instagram/ 看這則文章知道說原來IG更換網址的做法大概是怎麼樣子 但我不知道如何利用R來複製這件事情 https://toyo0103.blogspot.tw/2018/01/selenium-webdriver-instagram.html 看這則文章知道說如果用RSelenium的話可以一則一則點開後關掉 也有試著實作但遇到的問題是不知道該抓取哪個xpath或是css selector的節點 現在覺得困擾的是大概知道觀念但還是不知道如何實作...這樣真的很心癢難耐 目前的問題大概是這樣 謝謝大家! [環境敘述]: R version 3.4.3 (2017-11-30) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows >= 8 x64 (build 9200) Matrix products: default locale: [1] LC_COLLATE=Chinese (Traditional)_Taiwan.950 LC_CTYPE=Chinese (Traditional)_Taiwan.950 [3] LC_MONETARY=Chinese (Traditional)_Taiwan.950 LC_NUMERIC=C [5] LC_TIME=Chinese (Traditional)_Taiwan.950 attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] httr_1.3.1 jsonlite_1.5 forcats_0.2.0 stringr_1.2.0 dplyr_0.7.4 purrr_0.2.4 [7] readr_1.1.1 tidyr_0.8.0 tibble_1.4.2 ggplot2_2.2.1 tidyverse_1.2.1 rvest_0.3.2 [13] xml2_1.2.0 RSelenium_1.7.1 loaded via a namespace (and not attached): [1] reshape2_1.4.2 haven_1.1.1 lattice_0.20-35 colorspace_1.3-2 XML_3.98-1.11 rlang_0.1.6 [7] pillar_1.1.0 foreign_0.8-69 glue_1.2.0 semver_0.2.0 modelr_0.1.1 readxl_1.0.0 [13] bindrcpp_0.2 bindr_0.1 plyr_1.8.4 munsell_0.4.3 binman_0.1.0 gtable_0.2.0 [19] cellranger_1.1.0 caTools_1.17.1 psych_1.7.8 wdman_0.2.2 curl_2.8.1 parallel_3.4.3 [25] broom_0.4.3 Rcpp_0.12.13 openssl_0.9.7 scales_0.5.0 mnormt_1.5-5 hms_0.4.1 [31] stringi_1.1.5 grid_3.4.3 cli_1.0.0 tools_3.4.3 bitops_1.0-6 magrittr_1.5 [37] lazyeval_0.2.0 crayon_1.3.4 pkgconfig_2.0.1 lubridate_1.7.3 rstudioapi_0.7 assertthat_0.2.0 [43] R6_2.2.2 nlme_3.1-131 compiler_3.4.3 [關鍵字]: 爬蟲 instagram scrapy rvest Rselenium -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.112.25.100 ※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1524383509.A.81F.html
文章代碼(AID): #1Qt3yLWV (R_Language)
文章代碼(AID): #1Qt3yLWV (R_Language)