Compare commits
2 Commits
master
...
4play-dock
| Author | SHA1 | Date | |
|---|---|---|---|
| 0efbb81d23 | |||
| 4b83c47637 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -26,3 +26,4 @@ data/captcha/minecraft/
|
|||||||
!banner/*default*
|
!banner/*default*
|
||||||
scraper/curlie.html
|
scraper/curlie.html
|
||||||
icons/*
|
icons/*
|
||||||
|
node_modules/
|
||||||
|
|||||||
@@ -163,7 +163,3 @@ const FPLAY_EXTERNAL_ENDPOINT = null; # Change null to "https://your-endpoint.co
|
|||||||
**IMPORTANT:** By default, `localhost:3030` is what Firefox connects to. The render server is exposed at `localhost:3000`. Don't mix them up, otherwise you will get errors about an "invalid Upgrade header".
|
**IMPORTANT:** By default, `localhost:3030` is what Firefox connects to. The render server is exposed at `localhost:3000`. Don't mix them up, otherwise you will get errors about an "invalid Upgrade header".
|
||||||
|
|
||||||
If everything was done correctly, you should be seeing results on the Google scraper! You can set proxies in `data/config.php` for it, just like any other scraper.
|
If everything was done correctly, you should be seeing results on the Google scraper! You can set proxies in `data/config.php` for it, just like any other scraper.
|
||||||
|
|
||||||
In case it isn't clear, here is a visual representation of what you want to achieve:
|
|
||||||
|
|
||||||

|
|
||||||
|
|||||||
@@ -150,3 +150,7 @@ services:
|
|||||||
##### Tor
|
##### Tor
|
||||||
|
|
||||||
You can route incoming and outgoing requests through tor by following [docker tor documentation](./docker_tor.md)
|
You can route incoming and outgoing requests through tor by following [docker tor documentation](./docker_tor.md)
|
||||||
|
|
||||||
|
##### 4play
|
||||||
|
|
||||||
|
You can run the 4play sidecar by following the [docker 4play guide](./docker_4play.md)
|
||||||
|
|||||||
48
docs/docker_4play.md
Normal file
48
docs/docker_4play.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
### Running 4get and 4play via docker guide
|
||||||
|
|
||||||
|
This setup will run both 4get and the 4play sidecar
|
||||||
|
|
||||||
|
# Docker compose
|
||||||
|
|
||||||
|
```
|
||||||
|
# docker-compose.yaml
|
||||||
|
|
||||||
|
services:
|
||||||
|
fourget:
|
||||||
|
image: luuul/4get:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- FOURGET_PROTO=http
|
||||||
|
- FOURGET_SERVER_NAME=4get.ca
|
||||||
|
- FOURGET_FPLAY_EXTERNAL_ENDPOINT=http://fourplay:3000
|
||||||
|
- FOURGET_FPLAY_PASSWORD=cnc
|
||||||
|
- FOURGET_FPLAY_TIMEOUT=30000
|
||||||
|
- FOURGET_FPLAY_ENABLE_API=true
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
fourplay:
|
||||||
|
image: luuul/4get-4play:latest
|
||||||
|
environment:
|
||||||
|
- FOURPLAY_PORT=3030
|
||||||
|
- FOURPLAY_PASSWORD=cnc
|
||||||
|
- FOURPLAY_COMMAND_TIMEOUT=5000
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
- "3030:3030"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
There is a example docker compose file available [here](../extra/4play/docker-compose.yaml)
|
||||||
|
|
||||||
|
# Steps
|
||||||
|
|
||||||
|
1. start the services with
|
||||||
|
|
||||||
|
```
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
2. configure firefox
|
||||||
|
|
||||||
|
folllow the steps in [configure](./configure.md) for firefox setup
|
||||||
19
extra/4play/Dockerfile
Normal file
19
extra/4play/Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
FROM alpine:3.21
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk update && apk upgrade
|
||||||
|
RUN apk add nodejs npm
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
EXPOSE 3030
|
||||||
|
|
||||||
|
ENTRYPOINT ["node"]
|
||||||
|
CMD ["page-render.js"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
24
extra/4play/docker-compose.yaml
Normal file
24
extra/4play/docker-compose.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# docker-compose.yaml
|
||||||
|
|
||||||
|
services:
|
||||||
|
fourget:
|
||||||
|
image: luuul/4get:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- FOURGET_PROTO=http
|
||||||
|
- FOURGET_SERVER_NAME=4get.ca
|
||||||
|
- FOURGET_FPLAY_EXTERNAL_ENDPOINT=http://fourplay:3000
|
||||||
|
- FOURGET_FPLAY_PASSWORD=cnc
|
||||||
|
- FOURGET_FPLAY_TIMEOUT=30000
|
||||||
|
- FOURGET_FPLAY_ENABLE_API=true
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
fourplay:
|
||||||
|
image: luuul/4get-4play:latest
|
||||||
|
environment:
|
||||||
|
- FOURPLAY_PORT=3030
|
||||||
|
- FOURPLAY_PASSWORD=cnc
|
||||||
|
- FOURPLAY_COMMAND_TIMEOUT=5000
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
- "3030:3030"
|
||||||
47
extra/4play/package-lock.json
generated
Normal file
47
extra/4play/package-lock.json
generated
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "4play",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "4play",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "AGPL-3.0-only",
|
||||||
|
"dependencies": {
|
||||||
|
"@lawlers/4play": "^1.2.5",
|
||||||
|
"ws": "^8.21.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lawlers/4play": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lawlers/4play/-/4play-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-mHxCROszXwW3XWdE+OQldJcAo3Qs9bI20VME/ZiPUvz3G2kdJaDbrMSzSwVlHmju+3dydupIE48t/ektKtewhg==",
|
||||||
|
"license": "AGPL-3.0-only",
|
||||||
|
"dependencies": {
|
||||||
|
"ws": "^8.21.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.21.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.2.tgz",
|
||||||
|
"integrity": "sha512-54dMVAo4WIe6SKy3vBgN+9bJZqqQ8IMRevAkOLQALhi49qkkQDQfWdAZ8KQlXiEabw88ARXXdUrlvtbKQX+aKw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
extra/4play/package.json
Normal file
20
extra/4play/package.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "4play",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.lolcat.ca/lolcat/4get/"
|
||||||
|
},
|
||||||
|
"license": "AGPL-3.0-only",
|
||||||
|
"author": "lolcat",
|
||||||
|
"type": "commonjs",
|
||||||
|
"main": "page-render.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@lawlers/4play": "^1.2.5",
|
||||||
|
"ws": "^8.21.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,9 +2,9 @@ const fplay = require("@lawlers/4play");
|
|||||||
const http = require("http");
|
const http = require("http");
|
||||||
|
|
||||||
// 4play settings
|
// 4play settings
|
||||||
var port = 3030;
|
var port = parseInt(process.env.FOURGET_FPLAY_PASSWORD) || 3030;
|
||||||
var timeout = 30000;
|
var timeout = parseInt(process.env.FOURGET_FPLAY_TIMEOUT) || 30000;
|
||||||
var password = "cnc";
|
var password = process.env.FOURGET_FPLAY_PASSWORD || "cnc";
|
||||||
|
|
||||||
// ==================================================
|
// ==================================================
|
||||||
|
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ class google{
|
|||||||
config::FPLAY_EXTERNAL_ENDPOINT .
|
config::FPLAY_EXTERNAL_ENDPOINT .
|
||||||
"?url=" . urlencode($url) .
|
"?url=" . urlencode($url) .
|
||||||
"&pw=" . urlencode(config::FPLAY_PASSWORD) .
|
"&pw=" . urlencode(config::FPLAY_PASSWORD) .
|
||||||
"&container=" .// urlencode($container) .
|
"&container=" . urlencode($container) .
|
||||||
"&proxy=" . urlencode($proxy) .
|
"&proxy=" . urlencode($proxy) .
|
||||||
"&url_match=" . urlencode("&sei=") .
|
"&url_match=" . urlencode("&sei=") .
|
||||||
"&fail_url_match=" . urlencode("\/sorry\/");
|
"&fail_url_match=" . urlencode("\/sorry\/");
|
||||||
@@ -733,7 +733,7 @@ class google{
|
|||||||
$container = &$data["container"];
|
$container = &$data["container"];
|
||||||
|
|
||||||
//file_put_contents("scraper/google-jp.html", $html);
|
//file_put_contents("scraper/google-jp.html", $html);
|
||||||
//$html = file_get_contents("scraper/google-softcaptcha.html");
|
//$html = file_get_contents("scraper/google-jp.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
$out = [
|
$out = [
|
||||||
@@ -754,26 +754,9 @@ class google{
|
|||||||
|
|
||||||
$this->fuckhtml->load($html);
|
$this->fuckhtml->load($html);
|
||||||
|
|
||||||
// solve softcaptcha
|
// init
|
||||||
$softcaptcha = $this->detect_sorry();
|
$this->detect_sorry();
|
||||||
|
|
||||||
if($softcaptcha !== false){
|
|
||||||
|
|
||||||
$params["sei"] = $softcaptcha["sei"];
|
|
||||||
|
|
||||||
$data2 = $this->get(
|
|
||||||
$proxy,
|
|
||||||
"https://www.google.com/search",
|
|
||||||
$params,
|
|
||||||
$container
|
|
||||||
);
|
|
||||||
|
|
||||||
$html = &$data2["data"];
|
|
||||||
|
|
||||||
$this->fuckhtml->load($html);
|
|
||||||
$this->parsestyles();
|
$this->parsestyles();
|
||||||
}
|
|
||||||
|
|
||||||
$this->scrape_dimg($html);
|
$this->scrape_dimg($html);
|
||||||
$this->scrape_imagearr($html);
|
$this->scrape_imagearr($html);
|
||||||
|
|
||||||
@@ -1398,28 +1381,7 @@ class google{
|
|||||||
|
|
||||||
$this->fuckhtml->load($html);
|
$this->fuckhtml->load($html);
|
||||||
|
|
||||||
// parse all <style> tags
|
$this->detect_sorry();
|
||||||
$this->parsestyles();
|
|
||||||
|
|
||||||
// solve softcaptcha
|
|
||||||
$softcaptcha = $this->detect_sorry();
|
|
||||||
|
|
||||||
if($softcaptcha !== false){
|
|
||||||
|
|
||||||
$params["sei"] = $softcaptcha["sei"];
|
|
||||||
|
|
||||||
$data2 = $this->get(
|
|
||||||
$proxy,
|
|
||||||
"https://www.google.com/search",
|
|
||||||
$params,
|
|
||||||
$container
|
|
||||||
);
|
|
||||||
|
|
||||||
$html = &$data2["data"];
|
|
||||||
|
|
||||||
$this->fuckhtml->load($html);
|
|
||||||
$this->parsestyles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get javascript images
|
// get javascript images
|
||||||
$this->scrape_imagearr($html);
|
$this->scrape_imagearr($html);
|
||||||
@@ -1601,32 +1563,13 @@ class google{
|
|||||||
|
|
||||||
$this->fuckhtml->load($html);
|
$this->fuckhtml->load($html);
|
||||||
|
|
||||||
// parse all <style> tags
|
|
||||||
$this->parsestyles();
|
|
||||||
|
|
||||||
// solve softcaptcha
|
|
||||||
$softcaptcha = $this->detect_sorry();
|
|
||||||
|
|
||||||
if($softcaptcha !== false){
|
|
||||||
|
|
||||||
$params["sei"] = $softcaptcha["sei"];
|
|
||||||
|
|
||||||
$data2 = $this->get(
|
|
||||||
$proxy,
|
|
||||||
"https://www.google.com/search",
|
|
||||||
$params,
|
|
||||||
$container
|
|
||||||
);
|
|
||||||
|
|
||||||
$html = &$data2["data"];
|
|
||||||
|
|
||||||
$this->fuckhtml->load($html);
|
|
||||||
$this->parsestyles();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Parse web video page
|
// Parse web video page
|
||||||
//
|
//
|
||||||
|
$this->detect_sorry();
|
||||||
|
|
||||||
|
// parse all <style> tags
|
||||||
|
$this->parsestyles();
|
||||||
|
|
||||||
// get javascript images
|
// get javascript images
|
||||||
$this->scrape_dimg($html);
|
$this->scrape_dimg($html);
|
||||||
@@ -1944,32 +1887,14 @@ class google{
|
|||||||
|
|
||||||
$this->fuckhtml->load($html);
|
$this->fuckhtml->load($html);
|
||||||
|
|
||||||
// parse styles
|
$this->detect_sorry();
|
||||||
$this->parsestyles();
|
|
||||||
|
|
||||||
// solve softcaptcha
|
|
||||||
$softcaptcha = $this->detect_sorry();
|
|
||||||
|
|
||||||
if($softcaptcha !== false){
|
|
||||||
|
|
||||||
$params["sei"] = $softcaptcha["sei"];
|
|
||||||
|
|
||||||
$data2 = $this->get(
|
|
||||||
$proxy,
|
|
||||||
"https://www.google.com/search",
|
|
||||||
$params,
|
|
||||||
$container
|
|
||||||
);
|
|
||||||
|
|
||||||
$html = &$data2["data"];
|
|
||||||
|
|
||||||
$this->fuckhtml->load($html);
|
|
||||||
$this->parsestyles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get images
|
// get images
|
||||||
$this->scrape_dimg($html);
|
$this->scrape_dimg($html);
|
||||||
|
|
||||||
|
// parse styles
|
||||||
|
$this->parsestyles();
|
||||||
|
|
||||||
$center_col =
|
$center_col =
|
||||||
$this->fuckhtml
|
$this->fuckhtml
|
||||||
->getElementById(
|
->getElementById(
|
||||||
@@ -2728,7 +2653,6 @@ class google{
|
|||||||
|
|
||||||
private function detect_sorry(){
|
private function detect_sorry(){
|
||||||
|
|
||||||
// detect recaptcha
|
|
||||||
$captcha_form =
|
$captcha_form =
|
||||||
$this->fuckhtml
|
$this->fuckhtml
|
||||||
->getElementById(
|
->getElementById(
|
||||||
@@ -2758,35 +2682,5 @@ class google{
|
|||||||
|
|
||||||
throw new Exception("Google returned a JS challenge");
|
throw new Exception("Google returned a JS challenge");
|
||||||
}
|
}
|
||||||
|
|
||||||
// bypass soft captcha
|
|
||||||
// "Verifying your request
|
|
||||||
// You'll be able to continue in a few seconds. Don't refresh this page."
|
|
||||||
$scripts =
|
|
||||||
$this->fuckhtml
|
|
||||||
->getElementsByTagName(
|
|
||||||
"script"
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach($scripts as $sc){
|
|
||||||
|
|
||||||
if(
|
|
||||||
preg_match(
|
|
||||||
'/var eid ?= ?\'(.*)\'[\S\s]*, ?([0-9]+)\);/U',
|
|
||||||
$sc["innerHTML"],
|
|
||||||
$matches
|
|
||||||
)
|
|
||||||
){
|
|
||||||
|
|
||||||
sleep(10); // gotta sleep to not trigger captcha. blame google, not me
|
|
||||||
|
|
||||||
return [
|
|
||||||
"sei" => $matches[1],
|
|
||||||
"timeout" => (int)$matches[2] // set to 10000 usually
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false; // no need to bypass
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user