Scrapy splash — loop сохраняет все значения только для одного элемента

#python #web-scraping #scrapy

#python #очистка веб-страниц #scrapy

Вопрос:

Я использую Scrapy с splash для очистки значений веб-сайта на основе Javascript. Код работает нормально, и spider удаляет все интересные значения. Проблема в том, что он сохраняет все эти значения только в один элемент.

 class Spider(CrawlSpider):
    name = "test"
    start_urls = ["http://example.com/results"]

    rules = (
        Rule(LinkExtractor(restrict_xpaths = ('//div[contains(@class, "products")]'), ),
             callback="parse",
             follow=False),)

    def start_requests(self):
       for url in self.start_urls:

           yield SplashRequest(url,callback=self.parse, endpoint='render.html', args={'wait':25.5})

    def parse(self, response):

       product_list = response.xpath('//div[contains(@class, "products")]').extract()

       for items in product_list:
          item=TestItem()
          item['CompanyName'] = response.xpath('').extract()
          item['Revenue'] = response.xpath('').extract()
          item['Tag'] = response.xpath('').extract()
          yield item
  

Я не вижу ничего плохого в приведенном выше коде. Все мои элементы находятся в одном div. Но существуют многопоточные div-файлы, содержащие эти элементы. Веб-сайт показывает много результатов на одной странице, с которой мне нужно взять эти значения. Например, в div products есть 10 разных divs, содержащих указанные элементы.

Вывод выглядит следующим образом:

 CompanyName,Tagline,Revenue
XcompanyName, YcomapnyName, ZCompanyName
Xtagline, Ytagline, Ztagline
Xrevenue, Yrevenue, Zrevenue
  

Хотя я хочу, чтобы это было:

 CompanyName,Tagline,Revenue
XcompanyName, Ytagline, Zrevenue
YcompanyName, Ytagline, Yrevenue
ZcompanyName, Ztagline, Zrevenue
  

CSS веб-сайта:

 <div class="products">
            <div id="ember1" class="product ember-view"><a href="/product/NameCompany" id="ember1" class="product-link ember-view">  <div class="product-card-header">
    <div id="ember1" class="product-card-logo ember-view"><img src="https://storage.googleapis.com/" id="ember1" class="product-avatar-img ember-view">
</div>
    <div class="product-card-header-t">
      <span class="product-card__name">NameCompany</span>
      <span class="product-card__tagline">Simple</span>
    </div>
  </div>

<!---->
    <div class="product-card-revenue">
      <div class="product-card-revenue-t">
        <span class="product-card-revenue-r">
          $0
          <span class="product-card-slash">/</span>
          <span class="product-card-period">month</span>
        </span>

        <span class="product-revenue">
<!---->          reported
        </span>
      </div>
    </div>
</div>
  

Редактировать:

Если я использую extract_first() в моем xpath для элементов, формат файла правильный, но он сохраняет информацию только из одного div и опускает остальные.

Комментарии:

1. Предоставьте ссылку, пожалуйста.

2. возможно, вам нужно items.xpath('').extract() вместо response.xpath('').extract()

3. Я добавил часть CSS, из которой были извлечены все элементы.

Ответ №1:

ответ @Umair был правильным

     def parse_attr(self, response):

       for items in response.xpath(''):
          item = TestItem()
          item['CompanyName'] = items.xpath('').extract()
          item['Revenue'] = items.xpath('').extract()
          item['Tag'] = items.xpath('').extract()
          yield item
  

Мне нужно было передать items (НЕ элемент) внутри цикла, а не объект ответа. Ответ был определен в области рассматриваемых divs. Теперь выходные данные имеют правильный формат.