这周公司组织了电影赏析,看的电影是《狗十三》。我之前并没有看过这部电影,就想着先去豆瓣上看一下评论。这电影的评论还不少,有好几百条,完全可以全爬下来,分析一下。拉到页面下面,点击后页,url就会跟着变化(start=那里),说明这也不是啥动态网页,完全可以写个循环,用rvest包一页一页的爬。但实际爬取的时候,遇到了问题,就是未登陆的状态下,只能爬前220条评论。我搜索了一下模拟登录的办法,似乎是成功了,但后续该怎么弄,我就不知道了。我在这里卡了一天,没想到解决办法。昨天早上躺在被窝里,突然想到,我之前研究了下用RSelenium爬取动态网页,这里我完全可以先用RSelenium模拟登录,然后把网页当成动态网页爬啊。试了一下,成功了,下面就是相关的操作过程。
首先还是载入需要用的包,要使用RSelenium包,还要先进行一些配置,具体内容可以看RSelenium包的官方网站(这网站好像需要科学上网):
library(tidyverse)
library(RSelenium)
library(rvest)
library(jiebaR)
library(wordcloud2)
library(knitr)
接下来跟Selenium Server进行连接,这里我用的是Chrome浏览器(变量名rd本应该在第一行,不知道为什么跑到下边去了……):
rd <- remoteDriver(
remoteServerAddr = "localhost",
port = 4444L,
browserName = "chrome"
)
然后模拟打开豆瓣电影的登录页面,输入用户名和密码,点击登录按键,就可以登录了:
rd$open()
rd$navigate('https://www.douban.com/accounts/login?source=movie')
we <- rd$findElement(using = 'xpath', '//*[@id="email"]')
we$sendKeysToElement(list('用户名'))
we <- rd$findElement(using = 'xpath', '//*[@id="password"]')
we$sendKeysToElement(list('密码'))
we <- rd$findElement(using = 'xpath', '//*[@id="lzform"]/div[6]/input')
we$clickElement()
如果没接触过爬虫的,看着上面的代码可能有点懵,但实际上没啥太玄奥的东西。RSelenium包中的函数名就明白显示了它是干什么的,而参数中的那些xpath,在Chrome浏览器中都是可以直接复制出来的。
后面就可以开始爬虫了。我只爬了评价星级、短评时间、有帮助次数和短评文本四项信息。需要说明的是,有些用户虽然写了短评,但不会打分,这种情况下,我认为的将其评价星级定位“无评价”。因为不打分也会影响后面内容的xpath,所以那部分用了一些if条件。另外,虽然不知道会不会用上,在每页的内容爬取完之后,我也会让程序随机休息几秒,省得被轻易地认定为是爬虫程序。
rd$navigate('https://movie.douban.com/subject/25716096/comments?start=0&limit=20&sort=new_score&status=P')
dog13 <- tibble()
for (i in 1:50) {
rank <- character(0)
time <- character(0)
help <- character(0)
text <- character(0)
temp <- tibble()
for (j in 1:20) {
xpath_rank <- str_c('//*[@id="comments"]/div[', j, ']/div[2]/h3/span[2]/span[2]')
we <- rd$findElement(using = 'xpath', xpath_rank)
rank[j] <- ifelse(str_length(we$getElementAttribute('title') %>% unlist()) > 2, '无评价', we$getElementAttribute('title') %>% unlist())
if (str_length(we$getElementAttribute('title') %>% unlist()) < 3) {
xpath_time <- str_c('//*[@id="comments"]/div[', j, ']/div[2]/h3/span[2]/span[3]')
we <- rd$findElement(using = 'xpath', xpath_time)
time[j] <- we$getElementText() %>% unlist()
} else {
xpath_time <- str_c('//*[@id="comments"]/div[', j, ']/div[2]/h3/span[2]/span[2]')
we <- rd$findElement(using = 'xpath', xpath_time)
time[j] <- we$getElementText() %>% unlist()
}
xpath_help <- str_c('//*[@id="comments"]/div[', j, ']/div[2]/h3/span[1]/span')
we <- rd$findElement(using = 'xpath', xpath_help)
help[j] <- we$getElementText() %>% unlist()
xpath_text <- str_c('//*[@id="comments"]/div[', j, ']/div[2]/p/span')
we <- rd$findElement(using = 'xpath', xpath_text)
text[j] <- we$getElementText() %>% unlist()
df <- tibble(rank, time, help, text)
}
dog13 <- bind_rows(dog13, df)
rest <- sample(1:10, 1)
if (i < 2) {
we <- rd$findElement(using = 'xpath', '//*[@id="paginator"]/a')
we$clickElement()
Sys.