使用Scrapy时了解无限加载-怎么了?

时间:2019-07-29 19:15:20

标签: python python-3.x web-scraping scrapy infinite-scroll

上下文

我正在尝试从this website获取所有数据,以便以后在某些模型训练项目(ML)中使用它们。

我选择使用Scrapy + Python 3.7来做到这一点。到目前为止,一切都很好。我已经建立了Scrapy项目结构,并开始研究刮板。为此,我创建了一些步骤,必须遵循这些步骤才能相应地获取所需的数据。

步骤

  1. 首先,我们可以看到,在访问site's sitemap时,我们可以获得所需的所有类别。 (也有直接的Products page,但不幸的是,无法以这种方式获取类别,所以这不是解决方案。)

enter image description here

  1. 现在,我们需要做的是访问每个子类别,这将使我们进入Products页面(无限加载所在的位置)。我以第一个子类别为例。

enter image description here

  1. 当我们向下滚动产品时,我们可以看到我们的负载无限大,并且正在请求将更多产品放入前端:

enter image description here

  1. 最后,单击每个产品并从中获取一些数据(该部分与我要的内容无关,因此您可以从下面粘贴的代码中跳过effectime_time类)

代码

我试图通过使用以下代码来重现以上内容:

Product

问题

我的代码存在的问题是,并非所有产品都被解析,只有70k中只有3k。现在,我认为问题出在148-165行之间。我已经通过调试器运行了它,但是我仍然不知道出了什么问题。

有人可以解释一下我的代码逻辑有什么问题吗?

2 个答案:

答案 0 :(得分:3)

不确定这是否是唯一的问题,因为我没有时间进行进一步的测试,但是当您在此处加载8批量数据时,您似乎只是在解析第一个产品:

# ...
product_url = scrapy.selector.Selector(text=products_str_html).xpath(
    '//div[@class="product-image-container"]//a/@href'
).get()
# ...

.get()方法不会返回所有网址。您可以改用getall()方法,该方法返回包含所有网址的列表:

# ...
product_url = scrapy.selector.Selector(text=products_str_html).xpath(
    '//div[@class="product-image-container"]//a/@href'
).getall()
# ...

然后循环遍历返回的列表并产生您之前产生的结果:

# ...
products_urls = scrapy.selector.Selector(text=products_str_html).xpath(
    '//div[@class="product-image-container"]//a/@href'
).getall()

for product_url in products_urls:
    yield scrapy.Request(
        f'https://bannersolutions.com{product_url}',
        callback=self.parse_product,
        meta={'product_category': response.meta.get('product_category')}
    )

答案 1 :(得分:1)

您在parse类的BannerSolutionsSpider方法中犯了同样的错误,就像在parse_plm方法中一样(由@Cajuu'突出显示)。而不是使用getall方法来获取所有超链接,而是使用了get方法,该方法仅返回每个子类别的第一个URL。

您可以尝试以下解决方案,它提供了所有子类别的URL进行解析。

for category in response.xpath('(//div[@class="col-md-3"])[1]/ul/li'):
    main_category_name = category.xpath('./a/text()').get()
    for sub_category in category.xpath('./ul/li'):
        sub_category_name = sub_category.xpath('./a/text()').get()
        sub_category_url = sub_category.xpath('./a/@href').get()
        yield scrapy.Request(f'https://bannersolutions.com{sub_category_url}', callback=self.parse_categories, meta={'product_category': f'{main_category_name}/{sub_category_name}'})