作者wenbuneatble (文本能吃吗)
看板R_Language
标题[问题] 用R爬Instagram
时间Sun Apr 22 15:51:32 2018
[问题类型]:使用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://webptt.com/cn.aspx?n=bbs/R_Language/M.1524383509.A.81F.html