Google Ads Clicker with Python, Selenium, and Tor-泓源视野

Google Ads Clicker with Python, Selenium, and Tor

Tor

How to click ads with different IPs.

Google Ads Clicker with Python, Selenium, and Tor插图
Photo by Pixabay from Pexels

Recently, someone from a local freelancing platform asked me to write a program to click ads for a given search query on Google. I sent him a sample but he decided not to buy it, so I decided to publish it here.

It uses the Tor network to change the IP address and Selenium with Python bindings for browser automation.

How to Setup Environment and Tor

You can follow the steps manually from this gist to set up Tor or use the following script to set up both virtual environment and Tor.

#!/bin/bash
project_dir=$(pwd)
# get password for Tor setup
tor_pwd=""
echo "Enter a password for tor network setup"
read tor_pwd
echo "Setting environment variable TOR_PWD..."
echo "export TOR_PWD=$tor_pwd" >> ~/.bashrc
source ~/.bashrc
cd $project_dir
echo "Installing Tor package..."
sudo apt update
sudo apt install -y tor
echo "Installing privoxy package..."
sudo apt install -y privoxy
# create virtual environment and activate
echo "Creating virtual environment..."
python -m venv env
source env/bin/activate
# install requirements
echo "Installing required packages..."
pip install wheel
pip install -r requirements.txt
# run as root
sudo su - <<EOF
echo "Making changes as root..."
port_enabled=$(egrep "^ControlPort 9051" /etc/tor/torrc)
if [[ -z "${port_enabled}" ]]; then echo "Enabling control port..." echo "ControlPort 9051" >> /etc/tor/torrc
fi
echo "Setting hashed Tor password..."
echo HashedControlPassword $(tor --hash-password "${tor_pwd}" | tail -n 1) >> /etc/tor/torrc
echo "Starting Tor service..."
service tor restart
echo "Setting privoxy config..."
echo "forward-socks5t / 127.0.0.1:9050 ." >> /etc/privoxy/config
service privoxy start
EOF
echo "::::: Setup Completed :::::"
# add run command as help
echo -e "\nRun the following commands to start"
echo "source env/bin/activate"
echo "python ad_clicker.py -q <search keywords>"

You should see the following output at the end of the run.

...
Enabling control port...
Setting hashed Tor password...
Starting Tor service...
::::: Setup Completed :::::Run the following commands to start
source env/bin/activate
python ad_clicker.py -q <search keywords>

Since your environment and Tor setup is ready at this point, we can continue with the implementation.

How to Implement the Ad Clicker Automation

After setting up Tor, it is easy to change your IP within Python code using the stem package.

from stem import Signal
from stem.control import Controller
def change_ip_address(password): """Change IP address over Tor connection :type password: str :param password: Tor authentication password """ logger.info("Changing ip address...") with Controller.from_port(port=9051) as controller: controller.authenticate(password=password) controller.signal(Signal.NEWNYM)

The script requires a query parameter with the -q option. If you used the ad_clicker_setup.sh script, the Tor authentication password will be received from the TOR_PWD environment variable. Otherwise, the user will be asked to type the password determined at the setup phase.

After IP is changed, a search on Google will be initiated for the given query. If there are ads in the results, they will be clicked in order.

def main(): arg_parser = get_arg_parser() args = arg_parser.parse_args() if not args.query: logger.error("Run with search query!") arg_parser.print_help() raise SystemExit() os.environ["WDM_LOG_LEVEL"] = "0" password = os.environ.get("TOR_PWD", None) if not password: password = getpass.getpass("Enter tor password: ") change_ip_address(password) response = requests.get("https://api.myip.com", proxies={"https": "socks5h://127.0.0.1:9050"}) logger.info(f"Connecting with IP: {response.json()['ip']}") search_controller = SearchController(args.query) ads = search_controller.search_for_ads() if not ads: logger.info("No ads in the search results!") else: logger.info(f"Found {len(ads)} ads") search_controller.click_ads(ads) search_controller.end_search()
if __name__ == "__main__": main()

The SearchController class is the actual module that does the work. It starts the search and performs clicks for ads found.

def search_for_ads(self): """Start search for the given query and return ads if any :rtype: list :returns: List of (ad, ad_link) tuples """ logger.info(f"Starting search for {self._search_query}") search_input_box = self._driver.find_element(*self.SEARCH_INPUT) search_input_box.send_keys(self._search_query, Keys.ENTER) ad_links = [] try: wait = WebDriverWait(self._driver, timeout=10) results_loaded = wait.until(EC.presence_of_element_located((By.ID, "result-stats"))) if results_loaded: logger.info("Getting ad links...") ad_links = self._get_ad_links() except TimeoutException: logger.error("Timed out waiting for results!") self.end_search() return ad_links

The search_for_ads method first locates the search box and enters the search query. After results loaded, the _get_ad_links method locates all ads under the element with id tads, and found ads are returned.

After ads are found, the click_ads method opens them in a different tab by sending Control and left mouse key to the ad link element.

def click_ads(self, ads): """Click ads found :type ads: list :param ads: List of (ad, ad_link) tuples """ # store the ID of the original window original_window_handle = self._driver.current_window_handle for ad in ads: ad_link_element = ad[0] ad_link = ad[1] logger.info(f"Clicking {ad_link}...") # open link in a different tab ad_link_element.send_keys(Keys.CONTROL + Keys.RETURN) for window_handle in self._driver.window_handles: if window_handle != original_window_handle: self._driver.switch_to.window(window_handle) sleep(4) self._driver.close() break # go back to original window self._driver.switch_to.window(original_window_handle) sleep(1) # scroll the page to avoid elements remain outside of the view self._driver.execute_script("arguments[0].scrollIntoView(true);", ad_link_element)

After clicking all the ads, the end_search method closes the browser.

def end_search(self): """Close the browser""" self._driver.quit()

You can find the project here.

Google Ads Clicker with Python, Selenium, and Tor插图1
Execution of the ad_clicker.py

Thank you for your time.

本文由 泓源视野 作者:admin 发表,其版权均为 泓源视野 所有,文章内容系作者个人观点,不代表 泓源视野 对观点赞同或支持。如需转载,请注明文章来源。
13
admin

发表评论

Protected with IP Blacklist CloudIP Blacklist Cloud
您是第8234714 位访客, 您的IP是:[18.119.107.161]