我在網路上發現了一個腳本,可以讓你解析來自亞馬遜的產品卡。我只是需要一個解決這樣的問題的方法。
我在尋找一種解析亞馬遜產品卡的方法時絞盡腦汁。問題在於,亞馬遜針對不同的輸出使用不同的設計選項,特別是- 如果您需要使用搜尋查詢「bags」解析卡片- 卡片將按照我的需要垂直排列,但如果您採取,例如,「T卹」 –然後卡片將水平排列,這樣腳本就會出錯,它可以打開頁面,但不想滾動。
此外,在閱讀了用戶對如何繞過亞馬遜驗證碼感到困惑的各種文章後,我升級了腳本,現在它可以繞過驗證碼(它與 2captcha 一起使用)。該腳本在每次載入新頁面後都會檢查頁面上是否存在驗證碼,如果出現驗證碼,則會向 2capcha 伺服器發送請求,並在收到解決方案後替換它並繼續工作。
然而,如何繞過驗證碼並不是最困難的問題,因為這在當今是一件微不足道的任務。更迫切的問題是如何讓腳本不僅適用於垂直排列的產品卡,也適用於水平排列的產品卡。
下面我將詳細描述該腳本包含哪些內容,演示其工作原理,如果您可以幫助解決問題,如果您知道在腳本中添加(更改)什麼以便它可以在卡片的水平設置上工作,我將不勝感激。
目前該腳本至少可以在其有限的功能上為某人提供幫助。
那麼,讓我們把腳本一點一點拆開吧!
首先,腳本導入完成任務所需的模組
從 selenium 導入 webdriver
從 selenium.webdriver.common.keys 匯入金鑰
從 selenium.webdriver.common.action_chains 導入 ActionChains
從 selenium.webdriver.support.ui 導入 WebDriverWait
從 selenium.webdriver.support 導入預期條件作為 EC
導入 csv
導入作業系統
從時間開始導入睡眠
導入請求
讓我們把它拆成幾個部分:
從 selenium 導入 webdriver
匯入 webdriver 類,它允許您透過腳本控制瀏覽器(在我的例子中是 Firefox)
來自 selenium.webdriver.common.by 導入
導入 theBy 類,腳本將透過該類搜尋要透過 XPath 解析的元素(它可以搜尋其他屬性,但在本例中將使用 Xpath)
從 selenium.webdriver.common.keys 匯入金鑰
導入 Keys 類,該類將用於模擬擊鍵,在此腳本中,它將向下滾動頁面 Keys.PAGE_DOWN
從 selenium.webdriver.common.action_chains 導入 ActionChains
匯入 ActionChains 類別來建立複雜的順序操作,在我們的例子中 - 點擊 PAGE_DOWN 按鈕並等待頁面上的所有元素加載(因為在 Amazon 上卡片在滾動時加載)
從 selenium.webdriver.support.ui 導入 WebDriverWait
導入 WebDriverWait 類,該類會等待加載我們要查找的信息,例如產品描述,我們將通過 Xpath 搜索該信息
從selenium.webdriver.support導入expected_conditions作為EC
它匯入了expected_conditions類別(縮寫為EC),它與前一個類別一起工作,並告訴WebDriverWait它需要等待哪個特定條件。這提高了腳本的可靠性,使其不會開始與尚未載入的內容互動。
導入 csv
匯入 csv 模組以處理 csv 檔案。
導入作業系統
匯入 os 模組以與作業系統搭配使用(建立目錄、檢查檔案是否存在等)。
從時間導入睡眠
我們匯入 sleep 函數 - 這是將腳本暫停特定時間(在我的例子中為 2 秒,但您可以設定更多)的函數,以便元素在滾動時加載。
導入請求
匯入用於傳送 HTTP 請求的 requests 庫,以與 2captcha 識別服務互動。
導入所有內容後,腳本開始配置瀏覽器以進行工作,特別是:
安裝API金鑰以存取2captcha服務
# 2Captcha 的 API 金鑰
API_KEY =
腳本包含一個為瀏覽器安裝的使用者代理程式(當然可以更改)。之後,瀏覽器將以指定的設定啟動。
`user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, 如 Gecko) Chrome/91.0.4472.124 Safari/537.36"
選項 = webdriver.FirefoxOptions()
options.add_argument(f"user-agent={user_agent}")
driver = webdriver.Firefox(options=options)
`
接下來是驗證碼解決方案模組。這正是用戶在搜尋如何解決驗證碼時正在尋找的地方。我們很長時間不會分析這段程式碼,因為它沒有什麼特別的問題。
簡而言之,腳本在每次頁面加載後,都會檢查頁面上是否存在驗證碼,如果發現它,則通過將其發送到 2captcha 伺服器來解決它。如果沒有驗證碼,則繼續執行。
`defsolve_captcha(驅動程式):
# 檢查頁面上是否存在驗證碼
嘗試:
captcha_element = driver.find_element(By.CLASS_NAME, 'g-recaptcha')
如果驗證碼元素:
print("偵測到驗證碼。正在解決...")
site_key = captcha_element.get_attribute('data-sitekey')
current_url = driver.current_url
# Send captcha request to 2Captcha captcha_id = requests.post( 'http://2captcha.com/in.php', data={ 'key': API_KEY, 'method': 'userrecaptcha', 'googlekey': site_key, 'pageurl': current_url } ).text.split('|')[1] # Wait for the captcha to be solved recaptcha_answer = '' while True: sleep(5) response = requests.get(f"http://2captcha.com/res.php?key={API_KEY}&action=get&id={captcha_id}") if response.text == 'CAPCHA_NOT_READY': continue if 'OK|' in response.text: recaptcha_answer = response.text.split('|')[1] break # Inject the captcha answer into the page driver.execute_script(f'document.getElementById("g-recaptcha-response").innerHTML = "{recaptcha_answer}";') driver.find_element(By.ID, 'submit').click() sleep(5) print("Captcha solved.") except Exception as e: print("No captcha found or error occurred:", e)
解析
接下來是負責對頁面進行排序、載入和滾動的程式碼部分
嘗試:
base_url = "https://www.amazon.in/s?k=bags"
for page_number in range(1, 10): page_url = f"{base_url}&page={page_number}" driver.get(page_url) driver.implicitly_wait(10) solve_captcha(driver) WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//span[@class="a-size-medium a-color-base a-text-normal"]'))) for _ in range(5): ActionChains(driver).send_keys(Keys.PAGE_DOWN).perform() sleep(2)
`
接下來是產品資料的收集。最重要的部分。在此部分中,腳本檢查載入的頁面並取得從那裡指定的資料。在我們的例子中,它是產品名稱、評論數量、價格、URL、產品評級。
`product_name_elements = driver.find_elements(By.XPATH, '//span[@class="a-size-medium a-color-base a-text-normal"]')
rating_number_elements = driver.find_elements(By.XPATH, '//span[@class="a-size-base s-underline-text"]')
star_ rating_elements = driver.find_elements(By.XPATH, '//span[@class="a-icon-alt"]')
Price_elements = driver.find_elements(By.XPATH, '//span[@class="a-price-whole"]')
Product_urls = driver.find_elements(By.XPATH, '//a[@class="a-link-normal s-underline-text s-underline-link-text s-link-style a-text-normal"]')
product_names = [element.text for element in product_name_elements] rating_numbers = [element.text for element in rating_number_elements] star_ratings = [element.get_attribute('innerHTML') for element in star_rating_elements] prices = [element.text for element in price_elements] urls = [element.get_attribute('href') for element in product_urls]
`
接下來,將指定的資料上傳到資料夾(為每個頁面建立csv文件,並將其儲存到輸出文件資料夾中)。如果該資料夾遺失,腳本會建立它。
`output_directory = "輸出檔"
如果不是 os.path.exists(output_directory):
os.makedirs(輸出目錄)
with open(os.path.join(output_directory, f'product_details_page_{page_number}.csv'), 'w', newline='', encoding='utf-8') as csvfile: csv_writer = csv.writer(csvfile) csv_writer.writerow(['Product Urls', 'Product Name', 'Product Price', 'Rating', 'Number of Reviews']) for url, name, price, star_rating, num_ratings in zip(urls, product_names, prices, star_ratings, rating_numbers): csv_writer.writerow([url, name, price, star_rating, num_ratings])
`
最後階段是工作的完成和資源的釋放。
最後:
driver.quit()
完整腳本
`從 selenium 導入 webdriver
從 selenium.webdriver.common.by 導入 By
從 selenium.webdriver.common.keys 匯入金鑰
從 selenium.webdriver.common.action_chains 導入 ActionChains
從 selenium.webdriver.support.ui 導入 WebDriverWait
從 selenium.webdriver.support 導入預期條件作為 EC
導入 csv
導入作業系統
從時間開始導入睡眠
導入請求
API_KEY = "您的 API 金鑰"
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, 如 Gecko) Chrome/91.0.4472.124 Safari/537.36"
選項 = webdriver.FirefoxOptions()
options.add_argument(f"user-agent={user_agent}")
driver = webdriver.Firefox(options=options)
defsolve_captcha(驅動程式):
# 檢查頁面上是否存在驗證碼
嘗試:
captcha_element = driver.find_element(By.CLASS_NAME, 'g-recaptcha')
如果驗證碼元素:
print("偵測到驗證碼。正在解決...")
site_key = captcha_element.get_attribute('data-sitekey')
current_url = driver.current_url
# Send captcha request to 2Captcha captcha_id = requests.post( 'http://2captcha.com/in.php', data={ 'key': API_KEY, 'method': 'userrecaptcha', 'googlekey': site_key, 'pageurl': current_url } ).text.split('|')[1] # Wait for the captcha to be solved recaptcha_answer = '' while True: sleep(5) response = requests.get(f"http://2captcha.com/res.php?key={API_KEY}&action=get&id={captcha_id}") if response.text == 'CAPCHA_NOT_READY': continue if 'OK|' in response.text: recaptcha_answer = response.text.split('|')[1] break # Inject the captcha answer into the page driver.execute_script(f'document.getElementById("g-recaptcha-response").innerHTML = "{recaptcha_answer}";') driver.find_element(By.ID, 'submit').click() sleep(5) print("Captcha solved.") except Exception as e: print("No captcha found or error occurred:", e)
嘗試:
# 起始頁 URL
base_url = "https://www.amazon.in/s?k=bags"
for page_number in range(1, 2): page_url = f"{base_url}&page={page_number}" driver.get(page_url) driver.implicitly_wait(10) # Attempt to solve captcha if detected solve_captcha(driver) # Explicit Wait WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//span[@class="a-size-medium a-color-base a-text-normal"]'))) for _ in range(5): ActionChains(driver).send_keys(Keys.PAGE_DOWN).perform() sleep(2) product_name_elements = driver.find_elements(By.XPATH, '//span[@class="a-size-medium a-color-base a-text-normal"]') rating_number_elements = driver.find_elements(By.XPATH, '//span[@class="a-size-base s-underline-text"]') star_rating_elements = driver.find_elements(By.XPATH, '//span[@class="a-icon-alt"]') price_elements = driver.find_elements(By.XPATH, '//span[@class="a-price-whole"]') product_urls = driver.find_elements(By.XPATH, '//a[@class="a-link-normal s-underline-text s-underline-link-text s-link-style a-text-normal"]') # Extract and print the text content of each product name, number of ratings, and star rating, urls product_names = [element.text for element in product_name_elements] rating_numbers = [element.text for element in rating_number_elements] star_ratings = [element.get_attribute('innerHTML') for element in star_rating_elements] prices = [element.text for element in price_elements] urls = [element.get_attribute('href') for element in product_urls] sleep(5) output_directory = "output files" if not os.path.exists(output_directory): os.makedirs(output_directory) with open(os.path.join(output_directory, f'product_details_page_{page_number}.csv'), 'w', newline='', encoding='utf-8') as csvfile: csv_writer = csv.writer(csvfile) csv_writer.writerow(['Product Urls', 'Product Name', 'Product Price', 'Rating', 'Number of Reviews']) for url, name, price, star_rating, num_ratings in zip(urls, product_names, prices, star_ratings, rating_numbers): csv_writer.writerow([url, name, price, star_rating, num_ratings])
最後:
driver.quit()
`
這樣腳本就不會出現錯誤,但只適用於垂直產品卡。以下是該腳本如何運作的範例。
如果您對此有什麼想說的,我很樂意在評論中討論。
以上是亞馬遜解析簡單且完全由您自己完成的詳細內容。更多資訊請關注PHP中文網其他相關文章!