SIM*_*SIM 4 python selenium web-scraping python-3.x selenium-webdriver
我已经使用 selenium 在 python 中编写了一些脚本来从 redmart 网站上抓取不同产品的名称和价格。我的爬虫点击一个链接,转到它的目标页面,从那里解析数据。但是,我在使用此爬网程序时面临的问题是,由于网页的加载速度较慢,它从页面中抓取的项目很少。如何从控制延迟加载过程的每个页面获取所有数据?我尝试使用“执行脚本”方法,但我做错了。这是我正在尝试的脚本:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://redmart.com/bakery")
wait = WebDriverWait(driver, 10)
counter = 0
while True:
try:
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "li.image-facets-pill")))
driver.find_elements_by_css_selector('img.image-facets-pill-image')[counter].click()
counter += 1
except IndexError:
break
# driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
for elems in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "li.productPreview"))):
name = elems.find_element_by_css_selector('h4[title] a').text
price = elems.find_element_by_css_selector('span[class^="ProductPrice__"]').text
print(name, price)
driver.back()
driver.quit()
Run Code Online (Sandbox Code Playgroud)
小智 5
我想您可以为此使用 Selenium,但是如果 @Andersson 在 Stackoverflow上的另一个问题中为您制作了代码后您担心速度,那么您应该复制 API 调用,该站点使用该调用并从 JSON 中提取数据 -就像网站一样。
如果您使用 Chrome Inspector,您将看到外部 while 循环(原始代码中的 try 块)中的每个类别的站点都调用 API,该 API 返回站点的整体类别。所有这些数据都可以像这样检索:
categories_api = 'https://api.redmart.com/v1.5.8/catalog/search?extent=0&depth=1'
r = requests.get(categories_api).json()
Run Code Online (Sandbox Code Playgroud)
对于下一个 API 调用,您需要获取有关面包店内容的 uri。这可以像这样完成:
bakery_item = [e for e in r['categories'] if e['title'] == 'Bakery]
children = bakery_item[0]['children']
uris = [c['uri'] for c in children]
Run Code Online (Sandbox Code Playgroud)
Uris 现在将是一个字符串列表(['bakery-bread', 'breakfast-treats-212', 'sliced-bread-212', 'wraps-pita-indian-breads', 'rolls-buns-212', “烘焙食品,甜点”,“面包,手工-面包-212”,“冻结部分烘烤”,“长寿命,面包吐司”,“专业-212”]) ,你会传递给Chrome Inspector 发现的另一个 API,该网站用于加载内容。
此 API 具有以下形式(默认返回较小的 pageSize,但我将其提高到 500,以确保您在一个请求中获得所有数据):
items_API = 'https://api.redmart.com/v1.5.8/catalog/search?pageSize=500&sort=1024&category={}'
for uri in uris:
r = requests.get(items_API.format(uri)).json()
products = r['products']
for product in products:
name = product['title']
# testing for promo_price - if its 0.0 go with the normal price
price = product['pricing']['promo_price']
if price == 0.0:
price = product['pricing']['price']
print("Name: {}. Price: {}".format(name, price))
Run Code Online (Sandbox Code Playgroud)
编辑:如果你仍然想坚持使用硒,你可以插入这样的东西来处理延迟加载。关于滚动的问题之前已经回答过多次,所以你的实际上是重复的。将来,您应该展示您尝试过的内容(您自己在执行部分的努力)并显示回溯。
check_height = driver.execute_script("return document.body.scrollHeight;")
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
height = driver.execute_script("return document.body.scrollHeight;")
if height == check_height:
break
check_height = height
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4239 次 |
| 最近记录: |