mirror of
https://github.com/FlareSolverr/FlareSolverr.git
synced 2025-12-05 17:18:19 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7af311b73c | ||
|
|
daec97532d | ||
|
|
8d7ed48f21 | ||
|
|
220f2599ae | ||
|
|
d772cf3f50 | ||
|
|
ab4365894b | ||
|
|
3fa9631559 | ||
|
|
04858c22fd | ||
|
|
5085ca6990 | ||
|
|
cd4df1e061 | ||
|
|
6c79783f7c | ||
|
|
4139e8d47c | ||
|
|
1942eb5fdc | ||
|
|
401bf5be76 | ||
|
|
d8ffdd3061 | ||
|
|
2d66590b08 | ||
|
|
a217510dc7 |
32
CHANGELOG.md
32
CHANGELOG.md
@@ -1,6 +1,36 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v3.3.3 (2023/08/03)
|
## v3.3.10 (2023/11/14)
|
||||||
|
|
||||||
|
* Add LANG ENV - resolves issues with YGGtorrent
|
||||||
|
|
||||||
|
## v3.3.9 (2023/11/13)
|
||||||
|
|
||||||
|
* Fix for Docker build, capture TypeError
|
||||||
|
|
||||||
|
## v3.3.8 (2023/11/13)
|
||||||
|
|
||||||
|
* Fix headless=true for Chrome 117+. Thanks @NabiKAZ
|
||||||
|
* Support running Chrome 119 from source. Thanks @koleg and @Chris7X
|
||||||
|
* Fix "OSError: [WinError 6] The handle is invalid" on exit. Thanks @enesgorkemgenc
|
||||||
|
|
||||||
|
## v3.3.7 (2023/11/05)
|
||||||
|
|
||||||
|
* Bump to rebuild. Thanks @JoachimDorchies
|
||||||
|
|
||||||
|
## v3.3.6 (2023/09/15)
|
||||||
|
|
||||||
|
* Update checkbox selector, again
|
||||||
|
|
||||||
|
## v3.3.5 (2023/09/13)
|
||||||
|
|
||||||
|
* Change checkbox selector, support languages other than English
|
||||||
|
|
||||||
|
## v3.3.4 (2023/09/02)
|
||||||
|
|
||||||
|
* Update checkbox selector
|
||||||
|
|
||||||
|
## v3.3.3 (2023/08/31)
|
||||||
|
|
||||||
* Update undetected_chromedriver to v3.5.3
|
* Update undetected_chromedriver to v3.5.3
|
||||||
|
|
||||||
|
|||||||
10
Dockerfile
10
Dockerfile
@@ -62,17 +62,17 @@ ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
|||||||
CMD ["/usr/local/bin/python", "-u", "/app/flaresolverr.py"]
|
CMD ["/usr/local/bin/python", "-u", "/app/flaresolverr.py"]
|
||||||
|
|
||||||
# Local build
|
# Local build
|
||||||
# docker build -t ngosang/flaresolverr:3.3.3 .
|
# docker build -t ngosang/flaresolverr:3.3.10 .
|
||||||
# docker run -p 8191:8191 ngosang/flaresolverr:3.3.3
|
# docker run -p 8191:8191 ngosang/flaresolverr:3.3.10
|
||||||
|
|
||||||
# Multi-arch build
|
# Multi-arch build
|
||||||
# docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
# docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||||
# docker buildx create --use
|
# docker buildx create --use
|
||||||
# docker buildx build -t ngosang/flaresolverr:3.3.3 --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8 .
|
# docker buildx build -t ngosang/flaresolverr:3.3.10 --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8 .
|
||||||
# add --push to publish in DockerHub
|
# add --push to publish in DockerHub
|
||||||
|
|
||||||
# Test multi-arch build
|
# Test multi-arch build
|
||||||
# docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
# docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||||
# docker buildx create --use
|
# docker buildx create --use
|
||||||
# docker buildx build -t ngosang/flaresolverr:3.3.3 --platform linux/arm/v7 --load .
|
# docker buildx build -t ngosang/flaresolverr:3.3.10 --platform linux/arm/v7 --load .
|
||||||
# docker run -p 8191:8191 --platform linux/arm/v7 ngosang/flaresolverr:3.3.3
|
# docker run -p 8191:8191 --platform linux/arm/v7 ngosang/flaresolverr:3.3.10
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ This also speeds up the requests since it won't have to launch a new browser ins
|
|||||||
| Parameter | Notes |
|
| Parameter | Notes |
|
||||||
|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| session | Optional. The session ID that you want to be assigned to the instance. If isn't set a random UUID will be assigned. |
|
| session | Optional. The session ID that you want to be assigned to the instance. If isn't set a random UUID will be assigned. |
|
||||||
| proxy | Optional, default disabled. Eg: `"proxy": {"url": "http://127.0.0.1:8888"}`. You must include the proxy schema in the URL: `http://`, `socks4://` or `socks5://`. Authorization (username/password) is supported. Eg: `"proxy": {"url": "http://127.0.0.1:8888", username": "testuser", "password": "testpass"}` |
|
| proxy | Optional, default disabled. Eg: `"proxy": {"url": "http://127.0.0.1:8888"}`. You must include the proxy schema in the URL: `http://`, `socks4://` or `socks5://`. Authorization (username/password) is supported. Eg: `"proxy": {"url": "http://127.0.0.1:8888", "username": "testuser", "password": "testpass"}` |
|
||||||
|
|
||||||
#### + `sessions.list`
|
#### + `sessions.list`
|
||||||
|
|
||||||
@@ -232,6 +232,7 @@ This is the same as `request.get` but it takes one more param:
|
|||||||
| LOG_HTML | false | Only for debugging. If `true` all HTML that passes through the proxy will be logged to the console in `debug` level. |
|
| LOG_HTML | false | Only for debugging. If `true` all HTML that passes through the proxy will be logged to the console in `debug` level. |
|
||||||
| CAPTCHA_SOLVER | none | Captcha solving method. It is used when a captcha is encountered. See the Captcha Solvers section. |
|
| CAPTCHA_SOLVER | none | Captcha solving method. It is used when a captcha is encountered. See the Captcha Solvers section. |
|
||||||
| TZ | UTC | Timezone used in the logs and the web browser. Example: `TZ=Europe/London`. |
|
| TZ | UTC | Timezone used in the logs and the web browser. Example: `TZ=Europe/London`. |
|
||||||
|
| LANG | none | Language used in the web browser. Example: `LANG=fr_FR`. |
|
||||||
| HEADLESS | true | Only for debugging. To run the web browser in headless mode or visible. |
|
| HEADLESS | true | Only for debugging. To run the web browser in headless mode or visible. |
|
||||||
| BROWSER_TIMEOUT | 40000 | If you are experiencing errors/timeouts because your system is slow, you can try to increase this value. Remember to increase the `maxTimeout` parameter too. |
|
| BROWSER_TIMEOUT | 40000 | If you are experiencing errors/timeouts because your system is slow, you can try to increase this value. Remember to increase the `maxTimeout` parameter too. |
|
||||||
| TEST_URL | https://www.google.com | FlareSolverr makes a request on start to make sure the web browser is working. You can change that URL if it is blocked in your country. |
|
| TEST_URL | https://www.google.com | FlareSolverr makes a request on start to make sure the web browser is working. You can change that URL if it is blocked in your country. |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "flaresolverr",
|
"name": "flaresolverr",
|
||||||
"version": "3.3.3",
|
"version": "3.3.10",
|
||||||
"description": "Proxy server to bypass Cloudflare protection",
|
"description": "Proxy server to bypass Cloudflare protection",
|
||||||
"author": "Diego Heras (ngosang / ngosang@hotmail.es)",
|
"author": "Diego Heras (ngosang / ngosang@hotmail.es)",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
|
|||||||
@@ -252,11 +252,11 @@ def _resolve_challenge(req: V1RequestBase, method: str) -> ChallengeResolutionT:
|
|||||||
def click_verify(driver: WebDriver):
|
def click_verify(driver: WebDriver):
|
||||||
try:
|
try:
|
||||||
logging.debug("Try to find the Cloudflare verify checkbox...")
|
logging.debug("Try to find the Cloudflare verify checkbox...")
|
||||||
iframe = driver.find_element(By.XPATH, "//iframe[@title='Widget containing a Cloudflare security challenge']")
|
iframe = driver.find_element(By.XPATH, "//iframe[starts-with(@id, 'cf-chl-widget-')]")
|
||||||
driver.switch_to.frame(iframe)
|
driver.switch_to.frame(iframe)
|
||||||
checkbox = driver.find_element(
|
checkbox = driver.find_element(
|
||||||
by=By.XPATH,
|
by=By.XPATH,
|
||||||
value='//*[@id="cf-stage"]//label[@class="ctp-checkbox-label"]/input',
|
value='//*[@id="challenge-stage"]/div/label/input',
|
||||||
)
|
)
|
||||||
if checkbox:
|
if checkbox:
|
||||||
actions = ActionChains(driver)
|
actions = ActionChains(driver)
|
||||||
|
|||||||
@@ -464,11 +464,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||||||
)
|
)
|
||||||
self.browser_pid = browser.pid
|
self.browser_pid = browser.pid
|
||||||
|
|
||||||
# Fix for Chrome 115
|
|
||||||
# https://github.com/seleniumbase/SeleniumBase/pull/1967
|
|
||||||
service = selenium.webdriver.chromium.service.ChromiumService(
|
service = selenium.webdriver.chromium.service.ChromiumService(
|
||||||
executable_path=self.patcher.executable_path,
|
self.patcher.executable_path
|
||||||
service_args=["--disable-build-check"]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
super(Chrome, self).__init__(
|
super(Chrome, self).__init__(
|
||||||
@@ -813,7 +811,11 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
|
|||||||
else:
|
else:
|
||||||
logger.debug("successfully removed %s" % self.user_data_dir)
|
logger.debug("successfully removed %s" % self.user_data_dir)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
try:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
# dereference patcher, so patcher can start cleaning up as well.
|
# dereference patcher, so patcher can start cleaning up as well.
|
||||||
# this must come last, otherwise it will throw 'in use' errors
|
# this must come last, otherwise it will throw 'in use' errors
|
||||||
|
|||||||
@@ -62,7 +62,17 @@ class Patcher(object):
|
|||||||
prefix = "undetected"
|
prefix = "undetected"
|
||||||
self.user_multi_procs = user_multi_procs
|
self.user_multi_procs = user_multi_procs
|
||||||
|
|
||||||
self.is_old_chromedriver = version_main and version_main <= 114
|
try:
|
||||||
|
# Try to convert version_main into an integer
|
||||||
|
version_main_int = int(version_main)
|
||||||
|
# check if version_main_int is less than or equal to e.g 114
|
||||||
|
self.is_old_chromedriver = version_main and version_main_int <= 114
|
||||||
|
except (ValueError,TypeError):
|
||||||
|
# If the conversion fails, print an error message
|
||||||
|
print("version_main cannot be converted to an integer")
|
||||||
|
# Set self.is_old_chromedriver to False if the conversion fails
|
||||||
|
self.is_old_chromedriver = False
|
||||||
|
|
||||||
# Needs to be called before self.exe_name is accessed
|
# Needs to be called before self.exe_name is accessed
|
||||||
self._set_platform_name()
|
self._set_platform_name()
|
||||||
|
|
||||||
|
|||||||
16
src/utils.py
16
src/utils.py
@@ -113,7 +113,7 @@ def create_proxy_extension(proxy: dict) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def get_webdriver(proxy: dict = None) -> WebDriver:
|
def get_webdriver(proxy: dict = None) -> WebDriver:
|
||||||
global PATCHED_DRIVER_PATH
|
global PATCHED_DRIVER_PATH, USER_AGENT
|
||||||
logging.debug('Launching web browser...')
|
logging.debug('Launching web browser...')
|
||||||
|
|
||||||
# undetected_chromedriver
|
# undetected_chromedriver
|
||||||
@@ -136,6 +136,14 @@ def get_webdriver(proxy: dict = None) -> WebDriver:
|
|||||||
# https://peter.sh/experiments/chromium-command-line-switches/#use-gl
|
# https://peter.sh/experiments/chromium-command-line-switches/#use-gl
|
||||||
options.add_argument('--use-gl=swiftshader')
|
options.add_argument('--use-gl=swiftshader')
|
||||||
|
|
||||||
|
language = os.environ.get('LANG', None)
|
||||||
|
if language is not None:
|
||||||
|
options.add_argument('--lang=%s' % language)
|
||||||
|
|
||||||
|
# Fix for Chrome 117 | https://github.com/FlareSolverr/FlareSolverr/issues/910
|
||||||
|
if USER_AGENT is not None:
|
||||||
|
options.add_argument('--user-agent=%s' % USER_AGENT)
|
||||||
|
|
||||||
proxy_extension_dir = None
|
proxy_extension_dir = None
|
||||||
if proxy and all(key in proxy for key in ['url', 'username', 'password']):
|
if proxy and all(key in proxy for key in ['url', 'username', 'password']):
|
||||||
proxy_extension_dir = create_proxy_extension(proxy)
|
proxy_extension_dir = create_proxy_extension(proxy)
|
||||||
@@ -162,10 +170,6 @@ def get_webdriver(proxy: dict = None) -> WebDriver:
|
|||||||
driver_exe_path = "/app/chromedriver"
|
driver_exe_path = "/app/chromedriver"
|
||||||
else:
|
else:
|
||||||
version_main = get_chrome_major_version()
|
version_main = get_chrome_major_version()
|
||||||
# Fix for Chrome 115
|
|
||||||
# https://github.com/seleniumbase/SeleniumBase/pull/1967
|
|
||||||
if int(version_main) > 114:
|
|
||||||
version_main = 114
|
|
||||||
if PATCHED_DRIVER_PATH is not None:
|
if PATCHED_DRIVER_PATH is not None:
|
||||||
driver_exe_path = PATCHED_DRIVER_PATH
|
driver_exe_path = PATCHED_DRIVER_PATH
|
||||||
|
|
||||||
@@ -295,6 +299,8 @@ def get_user_agent(driver=None) -> str:
|
|||||||
if driver is None:
|
if driver is None:
|
||||||
driver = get_webdriver()
|
driver = get_webdriver()
|
||||||
USER_AGENT = driver.execute_script("return navigator.userAgent")
|
USER_AGENT = driver.execute_script("return navigator.userAgent")
|
||||||
|
# Fix for Chrome 117 | https://github.com/FlareSolverr/FlareSolverr/issues/910
|
||||||
|
USER_AGENT = re.sub('HEADLESS', '', USER_AGENT, flags=re.IGNORECASE)
|
||||||
return USER_AGENT
|
return USER_AGENT
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception("Error getting browser User-Agent. " + str(e))
|
raise Exception("Error getting browser User-Agent. " + str(e))
|
||||||
|
|||||||
Reference in New Issue
Block a user