Tools to Work with the 'Splash' JavaScript Rendering Service in R
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
8.0 KiB

7 years ago
---
output: rmarkdown::github_document
---
`splashr` : Tools to Work with the 'Splash' JavaScript Rendering Service
7 years ago
TL;DR: This package works with Splash rendering servers which are really just a REST API & `lua` scripting interface to a QT browser. It's an alternative to the Selenium ecosystem which was really engineered for application testing & validation.
7 years ago
7 years ago
Sometimes, all you need is a page scrape after javascript has been allowed to roam wild and free over your meticulously crafted HTML tags. So, this package does not do _everything_ Selenium can, but if you're just trying to get a page back that needs javascript rendering, this is a nice alternative.
7 years ago
7 years ago
It's also an alternative to `phantomjs` (which you can use in R within or without a Selenium context as it's it's own webdriver) and it may be useful to compare renderings between this package & `phantomjs`.
7 years ago
You can also get it running with two commands:
sudo docker pull hrbrmstr/splashttpd
sudo docker run -p 5023:5023 -p 8050:8050 -p 8051:8051 hrbrmstr/splashttpd
7 years ago
(Do whatever you Windows ppl do with Docker on your systems to make ^^ work.)
If using the [`harbor`](https://github.com/wch/harbor) package you can use the convience wrappers in this pacakge:
install_splash()
splash_container <- start_splash()
and then run:
stop_splash(splash_container)
when done. All of that happens on your localhost so use `localhost` as the Splash server parameter.
7 years ago
You can run Selenium in Docker, so this is not unique to Splash. But, a Docker context makes it so that you don't have to run or maintain icky Python stuff directly on your system. Leave it in the abandoned warehouse district where it belongs.
7 years ago
All you need for this package to work is a running Splash instance. You provide the host/port for it and it's scrape-tastic fun from there!
7 years ago
### About Splash
7 years ago
>'Splash' <https://github.com/scrapinghub/splash> is a javascript rendering service. It’s a lightweight web browser with an 'HTTP' API, implemented in Python using 'Twisted'and 'QT' and provides some of the core functionality of the 'RSelenium' or 'seleniumPipes' R packages but with a Java-free footprint. The (twisted) 'QT' reactor is used to make the sever fully asynchronous allowing to take advantage of 'webkit' concurrency via QT main loop. Some of Splash features include the ability to process multiple webpages in parallel; retrieving HTML results and/or take screenshots; disabling images or use Adblock Plus rules to make rendering faster; executing custom JavaScript in page context; getting detailed rendering info in HAR format.
7 years ago
The following functions are implemented:
- `render_html`: Return the HTML of the javascript-rendered page.
7 years ago
- `render_file`: Return the HTML or image (png) of the javascript-rendered page in a local file
- `render_har`: Return information about Splash interaction with a website in [HAR](http://www.softwareishard.com/blog/har-12-spec/) format.
7 years ago
- `render_jpeg`: Return a image (in JPEG format) of the javascript-rendered page.
- `render_png`: Return a image (in PNG format) of the javascript-rendered page.
- `execute_lua`: Execute a custom rendering script and return a result.
7 years ago
- `splash`: Configure parameters for connecting to a Splash server
- `install_splash`: Retrieve the Docker image for Splash
- `start_splash`: Start a Splash server Docker container
- `stop_splash`: Stop a running a Splash server Docker container
7 years ago
Helpers:
- `get_body_size`: Retrieve size of content | body | headers
- `get_content_sie`: Retrieve size of content | body | headers
- `get_content_type` Retrieve or test content type of a HAR request object
- `get_headers_size` Retrieve size of content | body | headers
- `is_binary`: Retrieve or test content type of a HAR request object
- `is_content_type`: Retrieve or test content type of a HAR request object
- `is_css`: Retrieve or test content type of a HAR request object
- `is_gif`: Retrieve or test content type of a HAR request object
- `is_html`: Retrieve or test content type of a HAR request object
- `is_javascript`: Retrieve or test content type of a HAR request object
- `is_jpeg`: Retrieve or test content type of a HAR request object
- `is_json`: Retrieve or test content type of a HAR request object
- `is_plain`: Retrieve or test content type of a HAR request object
- `is_png`: Retrieve or test content type of a HAR request object
- `is_svg`: Retrieve or test content type of a HAR request object
7 years ago
- `is_xhr`: Retrieve or test content type of a HAR request object
- `is_xml`: Retrieve or test content type of a HAR request object
Some functions from `HARtools` are imported/exported and `%>%` is imported/exported.
7 years ago
### TODO
Suggest more in a feature req!
7 years ago
- <strike>Implement `render.json`</strike>
7 years ago
- <strike>Implement "file rendering"</strike>
- <strike>Implement `execute` (you can script Splash!)</strike>
7 years ago
- <strike>Add integration with [`HARtools`](https://github.com/johndharrison/HARtools)</strike>
- <strike>_Possibly_ writing R function wrappers to install/start/stop Splash</strike> which would also support enabling javascript profiles, request filters and proxy profiles from with R directly, using [`harbor`](https://github.com/wch/harbor)
7 years ago
- Testing results with all combinations of parameters
7 years ago
### Installation
```{r eval=FALSE}
devtools::install_github("hrbrmstr/splashr")
```
```{r message=FALSE, warning=FALSE, error=FALSE}
options(width=120)
```
### Usage
```{r message=FALSE, warning=FALSE, error=FALSE}
library(splashr)
library(magick)
library(rvest)
library(anytime)
library(hrbrmisc) # github
7 years ago
library(htmlwidgets)
library(DiagrammeR)
library(tidyverse)
7 years ago
# current verison
packageVersion("splashr")
splash("splash", 8050L) %>%
splash_active()
splash("splash", 8050L) %>%
splash_debug()
```
Notice the difference between a rendered HTML scrape and a non-rendered one:
```{r}
splash("splash", 8050L) %>%
render_html("http://marvel.com/universe/Captain_America_(Steve_Rogers)")
read_html("http://marvel.com/universe/Captain_America_(Steve_Rogers)")
```
You can also profile pages:
```{r}
splash("splash", 8050L) %>%
render_har("http://www.poynter.org/") -> har
print(har)
```
You can use [`HARtools::HARviewer`](https://github.com/johndharrison/HARtools/blob/master/R/HARviewer.R) — which this pkg import/exports — to get view the HAR in an interactive HTML widget.
Full web page snapshots are easy-peasy too:
7 years ago
```{r eval=FALSE}
splash("splash", 8050L) %>%
render_png("http://marvel.com/universe/Captain_America_(Steve_Rogers)")
```
```{r eval=TRUE, include=FALSE}
splash("splash", 8050L) %>%
render_png("http://marvel.com/universe/Captain_America_(Steve_Rogers)") %>%
image_write("img/cap.png")
```
![](img/cap.png)
```{r eval=FALSE}
splash("splash", 8050L) %>%
render_jpeg("http://marvel.com/universe/Captain_America_(Steve_Rogers)")
```
```{r eval=TRUE, include=FALSE}
splash("splash", 8050L) %>%
render_jpeg("http://marvel.com/universe/Captain_America_(Steve_Rogers)") %>%
image_write("img/cap.jpg")
```
![](img/cap.jpg)
### Executing custom Lua scripts
7 years ago
```{r}
lua_ex <- '
function main(splash)
splash:go("http://rud.is/b")
splash:wait(0.5)
local title = splash:evaljs("document.title")
return {title=title}
end
'
res <- splash("localhost") %>% execute_lua(lua_ex)
rawToChar(res) %>%
jsonlite::fromJSON()
7 years ago
```
### Rendering Widgets
```{r eval=FALSE}
splash_vm <- start_splash(add_tempdir=TRUE)
7 years ago
```
```{r}
DiagrammeR("
graph LR
A-->B
A-->C
C-->E
B-->D
C-->D
D-->F
E-->F
") %>%
saveWidget("/tmp/diag.html")
splash("localhost") %>%
render_file("/tmp/diag.html", output="html")
```
```{r eval=FALSE}
splash("localhost") %>%
render_file("/tmp/diag.html", output="png", wait=2)
```
![](img/diag.png)
```{r eval=FALSE}
7 years ago
stop_splash(splash_vm)
```
7 years ago
### Test Results
```{r message=FALSE, warning=FALSE, error=FALSE}
library(splashr)
library(testthat)
date()
test_dir("tests/")
```
7 years ago
### Code of Conduct
Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms.