Selenium 无法使用 python 抓取 Shopee 电子商务网站

Posted

技术标签:

【中文标题】Selenium 无法使用 python 抓取 Shopee 电子商务网站【英文标题】:Selenium can not scrape Shopee e-commerce site using python 【发布时间】:2019-09-11 00:40:56 【问题描述】:

我无法在 Shopee(电子商务网站)上获取产品价格。 我已经查看了@dmitrybelyakov(链接:Scraping AJAX e-commerce site using python)解决的问题。

该解决方案帮助我获得了产品的“名称”和“historical_sold”,但我无法获得产品的价格。我在 Json 字符串中找不到价格值。 因此,我尝试使用 selenium 通过 xpath 提取数据,但似乎失败了。

电商站链接:https://shopee.com.my/search?keyword=h370m

我的代码:

import time

from selenium import webdriver

import pandas as pd

path = r'C:\Users\\admin\\Desktop\\chromedriver_win32\\Chromedriver'

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('headless')
chrome_options.add_argument('window-size=1200x600')

browserdriver = webdriver.Chrome(executable_path = path,options=chrome_options)
link='https://shopee.com.my/search?keyword=h370m'
browserdriver.get(link)
productprice='//*[@id="main"]/div/div[2]/div[2]/div/div/div/div[2]/div/div/div[2]/div[1]/div/a/div/div[2]/div[1]'
productprice_printout=browserdriver.find_element_by_xpath(productname).text
print(productprice_printout)

当我运行该代码时,它会显示如下错误通知:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: "method":"xpath","selector":"//*[@id="main"]/div/div[2]/div[2]/div/div/div/div[2]/div/div/div[2]/div[1]/div/a/div/div[2]/div[1]"

请帮我看看 Shopee 上的产品价格!

【问题讨论】:

【参考方案1】:

您可以为网站使用请求和搜索 API

import requests

headers = 
    'User-Agent': 'Mozilla/5',
    'Referer': 'https://shopee.com.my/search?keyword=h370m'


url = 'https://shopee.com.my/api/v2/search_items/?by=relevancy&keyword=h370m&limit=50&newest=0&order=desc&page_type=search'  
r = requests.get(url, headers = headers).json()

for item in r['items']:
    print(item['name'], ' ', item['price'])

如果你想要大致相同的比例:

for item in r['items']:
    print(item['name'], ' ', 'RM' + str(item['price']/100000))

【讨论】:

感谢您的支持!这对我很有用。 您的代码正是我想要的。但是,当我使用没有“'Referer': 'shopee.com.my/search?keyword=h370m'”行的代码时,将无法给出价格值。您能否为我解释更多,以了解在这种情况下拥有和不拥有 Referer 之间的区别? 服务器期望从客户端发送某些标头。在这种情况下,它需要Referer 标头(请求此信息的页面)。 API 比使用浏览器更快、更可靠,如果可用,应该是您的首选。 我已应用您的指南来尝试获取特定商店的所有产品的名称和价格。 'import requests i=1 while ishopee.vn/shop/42575106/…' url = 'shopee.com.my/api/v2/search_items/…*i)+'&order=desc&page_type =shop' r = requests.get(url, headers = headers).json() for item in r['items']: print(item['name'], ' ', item['price']) i=我+1' 它只是在第一次运行时工作,但以下运行尝试未能给我价格,只需给出名称。这些尝试的输出如下: Cooler Master Hyper 212 Turbo Black CPU Cooler (RR-212TK-16P None 高品质 3 PIN UK TO IEC C5 NOTEBOOK POWER CABLE WITH FUSE None. 你能解释一下为什么它只是第一次工作当我将循环应用到您的解决方案中以扫描此类商店的所有产品时?【参考方案2】:

要使用Selenium 和Python 提取Shopee 上的产品价格,您可以使用以下解决方案:

代码块:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('start-maximized')
options.add_argument('disable-infobars')
options.add_argument('--disable-extensions')
browserdriver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
browserdriver.get('https://shopee.com.my/search?keyword=h370m')
WebDriverWait(browserdriver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='shopee-modal__container']//button[text()='English']"))).click()
print([my_element.text for my_element in WebDriverWait(browserdriver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//span[text()='RM']//following::span[1]")))])
print("Program Ended")

控制台输出:

['430.00', '385.00', '435.00', '409.00', '479.00', '439.00', '479.00', '439.00', '439.00', '403.20', '369.00', '420.00', '479.00', '465.00', '465.00']
Program Ended

【讨论】:

昨天,你的代码运行顺利,但今天我再次测试,输出如下:' at 0x000002660D40D840> Program Ended'。请帮我纠正它!谢谢。 @Huynh 这个解决方案应该可以完美运行。请尝试在干净的 Test Environment 中使用适当且匹配的 WebDriverChromeDriver 启动 Test Execution >Web 客户端Google Chrome 版本。仅供参考,我们已经发布了 Chrome v74.x,因此请交叉检查 Chrome 是否已更新。 (Session info: headless chrome=74.0.3729.108) (Driver info: chromedriver=74.0.3729.6) 这是我目前的 Chromedriver 和 Google Chrome 版本。不幸的是,它没有按预期工作。就在几天前,它运行良好,但现在不行。我不知道发生了什么! @Huynh 我们昨天推送了chrome=74.0,从今天开始使用chromedriver=74.0。评论还为时过早。我确信chrome=73.0chromedriver=73.0 会完美无缺。 感谢您的及时回复!最后,我发现您的原始代码运行良好,但您的代码的最新版本(由 Corey Goldberg 编辑)不是。很抱歉给您带来不便!【参考方案3】:

访问网站时。我遇到了这个弹出窗口https://gyazo.com/0a9cd82e2c9879a1c834a82cb15020bd。我猜,为什么 selenium 不能检测到你正在寻找的 xpath,是因为这个弹出窗口阻塞了元素。

在 selenium 会话开始后,试试这个:

popup=browserdriver.find_element_by_xpath('//*[@id="modal"]/div[1]/div[1]/div/div[3]/button[1]')
popup.click()

【讨论】:

感谢您的回答!不幸的是,这仍然行不通!

以上是关于Selenium 无法使用 python 抓取 Shopee 电子商务网站的主要内容,如果未能解决你的问题,请参考以下文章

Python 使用 Selenium 和 Beautiful Soup 抓取 JavaScript

如何使用Python和Selenium分页来抓取页面

如果通过 python selenium 和美丽的汤嵌套在视频内的源标签内,则无法抓取 src

如何通过 Python 使用 GeckoDriver 和 Firefox 使 Selenium 脚本无法检测?

无法在 python selenium 中使用 selenium chrome webdriver 定位元素

python+selenium+PhantomJS爬取网页动态加载内容