【发布时间】:2018-06-09 10:54:28
【问题描述】:
我试图从this website 获取所有产品,但不知何故,我认为我没有选择最好的方法,因为其中一些丢失了,我不知道为什么。这不是我第一次遇到这个问题。
我现在的做法是这样的:
- 转到网站的index page
- 从那里获取所有类别 (A-Z 0-9)
- 访问上述每个类别并从那里递归遍历所有子类别,直到到达产品页面
- 当我到达产品页面时,检查产品是否有更多 SKU。如果有,请获取链接。否则,这是唯一的 SKU。
现在,下面的代码可以工作,但它并没有得到所有的产品,而且我看不出它为什么会跳过一些产品的任何原因。也许我处理一切的方式是错误的。
from lxml import html
from random import randint
from string import ascii_uppercase
from time import sleep
from requests import Session
INDEX_PAGE = 'https://www.richelieu.com/us/en/index'
session_ = Session()
def retry(link):
wait = randint(0, 10)
try:
return session_.get(link).text
except Exception as e:
print('Retrying product page in {} seconds because: {}'.format(wait, e))
sleep(wait)
return retry(link)
def get_category_sections():
au = list(ascii_uppercase)
au.remove('Q')
au.remove('Y')
au.append('0-9')
return au
def get_categories():
html_ = retry(INDEX_PAGE)
page = html.fromstring(html_)
sections = get_category_sections()
for section in sections:
for link in page.xpath("//div[@id='index-{}']//li/a/@href".format(section)):
yield '{}?imgMode=m&sort=&nbPerPage=200'.format(link)
def dig_up_products(url):
html_ = retry(url)
page = html.fromstring(html_)
for link in page.xpath(
'//h2[contains(., "CATEGORIES")]/following-sibling::*[@id="carouselSegment2b"]//li//a/@href'
):
yield from dig_up_products(link)
for link in page.xpath('//ul[@id="prodResult"]/li//div[@class="imgWrapper"]/a/@href'):
yield link
for link in page.xpath('//*[@id="ts_resultList"]/div/nav/ul/li[last()]/a/@href'):
if link != '#':
yield from dig_up_products(link)
def check_if_more_products(tree):
more_prods = [
all_prod
for all_prod in tree.xpath("//div[@id='pm2_prodTableForm']//tbody/tr/td[1]//a/@href")
]
if not more_prods:
return False
return more_prods
def main():
for category_link in get_categories():
for product_link in dig_up_products(category_link):
product_page = retry(product_link)
product_tree = html.fromstring(product_page)
more_products = check_if_more_products(product_tree)
if not more_products:
print(product_link)
else:
for sku_product_link in more_products:
print(sku_product_link)
if __name__ == '__main__':
main()
现在,这个问题可能过于笼统,但我想知道当有人想从网站获取所有数据(在本例中为产品)时,是否有一个经验法则可以遵循。有人可以指导我完成发现处理此类场景的最佳方法的整个过程吗?
【问题讨论】:
-
跳过的是哪个,每次运行都是一样的还是每次都不一样?
-
据我所知,不同的。但这真的很难说,因为:我得到了 130k 种产品,其中 60% 以上是重复的。
-
“请引导我完成整个过程,找出处理这种情况的最佳方法是什么?”。我不认为有一个“过程”会一直有效。例如,一些网站采用了各种反抓取措施,使其难以做到这一点。它也可能是非法的。在 richelieu.com 的条款和条件中,它说“禁止 [...] 直接或间接使用任何数据挖掘方法或工具、搜索机器人或任何类似的自动化工具或方法来收集材料中的数据”( richelieu.com/filiales/RC/html/ConditionsAn.html).
-
@mzjn 是“最后更新于 2006 年 2 月 1 日”。但是,虽然这可能仍然适用,但我这样做是出于学习目的
-
为什么不使用 BeautifulSoup4?例如每次找到 ItemImg 类时,从前面的锚标记中获取 href,跟随该页面进入项目,使用类似的方法获取实际项目...
标签: python python-3.x web-scraping lxml