使用Scrapy的无限滚动刮网站

时间:2018-02-12 16:24:37

标签: javascript json python-3.x web-scraping scrapy

我正试图从https://us.letgo.com/en抓取我所在地区的旧物品作为个人项目。我发现此视频很有用https://youtu.be/EelmnSzykyI。但是,视频有一些微妙的差异没有帮助。

我需要的信息是通过json异步加载的。该网站每个滚动加载15个项目(初始加载除外,其中包含30个项目)。 json对象如下所示:https://search-products-pwa.letgo.com/api/products?country_code=US&offset=0&quadkey=0320030123201&num_results=30&distance_type=mi,接下来要加载的15个项目如下所示:https://search-products-pwa.letgo.com/api/products?country_code=US&offset=30&quadkey=0320030123201&num_results=15&distance_type=mi

当我加载第一个回复data = json.loads(response.text)时,它会返回30个项目的列表。第一项看起来像这样:

{'attributes': None,
 'category_id': 5,
 'created_at': '2018-02-12T15:40:56+00:00',
 'currency': 'USD',
 'description': None,
 'featured': False,
 'geo': {'city': 'Asheville',
  'country_code': 'US',
  'distance': 1.1703344331099,
  'lat': 35.5889898,
  'lng': -82.5308015,
  'zip_code': '28805'},
 'id': '6080a1db-b2af-44c2-bfd8-4cc7f1ded17f',
 'image_information': 'brown ukulele',
 'images': [{'id': 'b8e78e2e-65c4-4062-b89e-c775ef9f6bc9',
   'url': 'https://img.letgo.com/images/ab/da/e2/f6/abdae2f68e34170d8f1f22d2473d1153.jpeg'}],
 'language_code': 'US',
 'name': None,
 'owner': {'avatar_url': '',
  'banned': False,
  'city': 'Asheville',
  'country_code': 'US',
  'id': 'fb0f8657-0273-4fac-ba77-9965a1dc8794',
  'is_richy': False,
  'name': 'Brock G',
  'status': 'active',
  'zip_code': '28805'},
 'price': 100,
 'price_flag': 2,
 'rejected': False,
 'status': 1,
 'thumb': {'height': 1280,
  'url': 'https://img.letgo.com/images/ab/da/e2/f6/abdae2f68e34170d8f1f22d2473d1153.jpeg?impolicy=img_200',
  'width': 960},
 'updated_at': '2018-02-12T15:41:34+00:00'}

我的目标是创建一个for循环并提取出每个项目,然后继续下一个请求,加载另外15个项目,但我不知道如何做到这一点。请注意,附加请求参数如下: enter image description here

enter image description here

更新

我越来越接近,但似乎无法弄清楚如何简单地更新函数中的offset参数,该函数基本上是以递归方式调用自身:

class LetgoSpider(scrapy.Spider):
    name = 'letgo'
    allowed_domains = ['letgo.com/en']
    start_urls = ['https://search-products-pwa.letgo.com/api/products?country_code=US&offset=0&quadkey=0320030123201&num_results=50&distance_type=mi']

    def parse(self, response):
        data = json.loads(response.text)
        for used_item in data:
            if len(data) == 0:
                break
            try:
                title = used_item['name']
                price = used_item['price']
                description = used_item['description']
                date = used_item['updated_at']
                images = [img['url'] for img in used_item['images']]
                latitude = used_item['geo']['lat']
                longitude = used_item['geo']['lng']               
            except Exception:
                pass

        yield {'Title': title,
               'Price': price,
               'Description': description,
               'Date': date,
               'Images': images,
               'Latitude': latitude,
               'Longitude': longitude          
               }    

        i = 0
        for new_items_load in response:
            i += 50 
            offset = i
            new_request = 'https://search-products-pwa.letgo.com/api/products?country_code=US&offset=' + str(i) + \
                          '&quadkey=0320030123201&num_results=50&distance_type=mi'
            yield scrapy.Request(new_request, callback=self.parse)

1 个答案:

答案 0 :(得分:1)

不确定我是否理解你的问题。

如果您只需要知道如何定义参数,这可能是一种方式:

  let offset, num_results;
  for(let i = 0; i < max; i += 15) {
    offset = i;
    num_results = i + 15;
    [do the request with the parameters values]
  }