mirror of
https://github.com/mxrch/GHunt.git
synced 2026-10-18 05:40:31 +08:00
Successfully bypassed new Google Photos protection 🕺
This commit is contained in:
@@ -5,7 +5,7 @@ cfg = dict(
|
||||
"review_loc_by_id": r'{}\",.*?\[\[null,null,(.*?),(.*?)\]'
|
||||
},
|
||||
|
||||
headless = False, # if True, it doesn't show the browser while scraping GMaps reviews
|
||||
headless = True, # if True, it doesn't show the browser while scraping GMaps reviews
|
||||
ytb_hunt_always = False, # if True, search the Youtube channel everytime
|
||||
gmaps_radius = 30, # in km. The radius distance to create groups of gmaps reviews.
|
||||
gdocs_public_doc = "1jaEEHZL32t1RUN5WuZEnFpqiEPf_APYKrRBG9LhLdvE" # The public Google Doc to use it as an endpoint, to use Google's Search.
|
||||
|
||||
@@ -111,7 +111,7 @@ for user in data["matches"]:
|
||||
else:
|
||||
print("\nYoutube channel not found.")
|
||||
|
||||
gpics(gaiaID, client, cfg)
|
||||
gpics(gaiaID, client, cookies, cfg)
|
||||
reviews = gmaps.scrape(gaiaID, client, cookies, cfg)
|
||||
if reviews:
|
||||
confidence, locations = gmaps.get_confidence(reviews, cfg)
|
||||
|
||||
+96
-3
@@ -2,15 +2,108 @@ import httpx
|
||||
import re
|
||||
from io import BytesIO
|
||||
from lib.metadata import ExifEater
|
||||
from seleniumwire import webdriver
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from PIL import Image
|
||||
from lib.utils import *
|
||||
|
||||
|
||||
def gpics(gaiaID, client, cfg):
|
||||
def get_source(gaiaID, client, cookies, cfg):
|
||||
|
||||
baseurl = f"https://get.google.com/albumarchive/{gaiaID}/albums/profile-photos?hl=en"
|
||||
req = client.get(baseurl)
|
||||
if req.status_code != 200:
|
||||
return False
|
||||
|
||||
class element_has_substring_or_substring(object):
|
||||
"""An expectation for checking that an element has a particular css class.
|
||||
|
||||
locator - used to find the element
|
||||
returns the WebElement once it has the particular css class
|
||||
"""
|
||||
def __init__(self, locator, substring1, substring2):
|
||||
self.locator = locator
|
||||
self.substring1 = substring1
|
||||
self.substring2 = substring2
|
||||
|
||||
def __call__(self, driver):
|
||||
element = driver.find_element(*self.locator) # Finding the referenced element
|
||||
if self.substring1 in element.text:
|
||||
return self.substring1
|
||||
elif self.substring2 in element.text:
|
||||
return self.substring2
|
||||
else:
|
||||
return False
|
||||
|
||||
tmprinter = TMPrinter()
|
||||
chrome_options = Options()
|
||||
chrome_options.add_argument('--log-level=3')
|
||||
chrome_options.add_experimental_option('excludeSwitches', ['enable-logging'])
|
||||
if cfg["headless"]:
|
||||
chrome_options.add_argument("--headless")
|
||||
options = {
|
||||
'connection_timeout': None # Never timeout, otherwise it floods errors
|
||||
}
|
||||
|
||||
tmprinter.out("Starting browser...")
|
||||
|
||||
driverpath = get_driverpath()
|
||||
driver = webdriver.Chrome(executable_path=driverpath, seleniumwire_options=options, options=chrome_options)
|
||||
wait = WebDriverWait(driver, 30)
|
||||
|
||||
tmprinter.out("Setting cookies...")
|
||||
driver.get("https://get.google.com/robots.txt")
|
||||
for k,v in cookies.items():
|
||||
driver.add_cookie({'name': k, 'value': v})
|
||||
|
||||
tmprinter.out('Fetching Google Photos "Profile photos" album...')
|
||||
driver.get(f"https://get.google.com/albumarchive/{gaiaID}/albums/profile-photos?hl=en")
|
||||
|
||||
tmprinter.out('Fetching the Google Photos albums overview...')
|
||||
buttons = driver.find_elements(By.XPATH, "//button")
|
||||
for button in buttons:
|
||||
text = button.get_attribute('jsaction')
|
||||
if text and 'touchcancel' in text:
|
||||
button.click()
|
||||
break
|
||||
else:
|
||||
tmprinter.out("")
|
||||
print("Can't get the back button..")
|
||||
driver.close()
|
||||
return False
|
||||
|
||||
wait.until(EC.text_to_be_present_in_element((By.XPATH, "//body"), "Album Archive"))
|
||||
tmprinter.out("Got the albums overview !")
|
||||
no_photos_trigger = "reached the end"
|
||||
photos_trigger = " item"
|
||||
result = wait.until(element_has_substring_or_substring((By.XPATH, "//body"), photos_trigger, no_photos_trigger))
|
||||
if result == no_photos_trigger:
|
||||
stats = "notfound"
|
||||
else:
|
||||
stats = "found"
|
||||
tmprinter.out("")
|
||||
source = driver.page_source
|
||||
driver.close()
|
||||
|
||||
return {"stats": stats, "source": source}
|
||||
|
||||
def gpics(gaiaID, client, cookies, cfg):
|
||||
baseurl = "https://get.google.com/albumarchive/"
|
||||
|
||||
print(f"\nGoogle Photos : {baseurl + gaiaID}")
|
||||
req = client.get(baseurl + gaiaID)
|
||||
results = re.compile(cfg["regexs"]["albums"]).findall(req.text)
|
||||
out = get_source(gaiaID, client, cookies, cfg)
|
||||
if not out:
|
||||
print("=> Couldn't fetch the public photos.")
|
||||
return False
|
||||
if out["stats"] == "notfound":
|
||||
print("=> No album")
|
||||
return False
|
||||
|
||||
#open('debug.html', 'w').write(repr(out["source"]))
|
||||
results = re.compile(cfg["regexs"]["albums"]).findall(out["source"])
|
||||
|
||||
list_albums_length = len(results)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user