Почему scrapy говорит, что я выполняю итерацию по объекту ‘itemMeta’?

#python #web-scraping #beautifulsoup #scrapy

#python #веб-очистка #beautifulsoup #scrapy

Вопрос:

Я пытаюсь очистить веб-сайт, чтобы узнать немного больше о том, как работает scrapy. У меня есть небольшой опыт работы с запросами пакетов и bs4 (BeautifulSoup). Я работаю в среде miniconda3 на моем компьютере Ubuntu 20.04.1 LTS. Я использую python 3.7.

Я создал элемент с именем ‘PostscrapeItem’, который имеет только один атрибут: full_text = scrapy.Field () . Я не коснулся структуры проекта, который был автоматически создан scrapy.

Я создал паук, который должен находить только вхождения html-тега (’em’) на этой веб-странице: https://blog.scrapinghub.com/page/1 /

Вот код моего паука:

 import scrapy
from bs4 import BeautifulSoup
from postscrape.items import PostscrapeItem


class PostSpider(scrapy.Spider):
    name = "posts"

    start_urls = [
        'https://blog.scrapinghub.com/page/1/'
    ]

    def parse(self, response):
        so = BeautifulSoup(response.text, 'html.parser')
        item = PostscrapeItem()

        if so.find('em'):
            concatenated = ""
            text_samples = so.find_all('em')

            for t_s in text_samples:
                concatenated  = t_s.text

            item['full_text'] = concatenated

        return PostscrapeItem
 

Проблема, с которой я сталкиваюсь, заключается в том, что у меня возникает ошибка, когда я запускаю этот код с помощью ‘scrapy crawl posts’ в моем терминале, и в нем говорится: ‘TypeError: объект ‘ItemMeta’ не может быть итерирован
‘. Из того немногого, что я думаю, я знаю, единственный ItemMeta, который присутствует в моей программе, — это объект PostscrapeItem . Мне кажется, что я не выполняю итерацию по этому объекту в своем коде. Вот почему я спрашиваю вас.

Вот полное сообщение об ошибке:

 Traceback (most recent call last):  

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/utils/defer.py", 

line 117, in iter_errback

yield next(it)

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/utils/python.py", line 345, in __next__

return next(self.data)

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/utils/python.py", line 345, in __next__

return next(self.data)

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/core/spidermw.py", line 64, in _evaluate_iterable

for r in iterable:

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/spidermiddlewares/offsite.py", line 29, in process_spider_output

for x in result:

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/core/spidermw.py", line 64, in _evaluate_iterable

for r in iterable:

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/spidermiddlewares/referer.py", line 338, in <genexpr>

return (_set_referer(r) for r in result or ())

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/core/spidermw.py", line 64, in _evaluate_iterable

for r in iterable:

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/spidermiddlewares/urllength.py", line 37, in <genexpr>

return (r for r in result or () if _filter(r))

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/core/spidermw.py", line 64, in _evaluate_iterable

for r in iterable:

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/spidermiddlewares/depth.py", line 58, in <genexpr>

return (r for r in result or () if _filter(r))

File "/home/luc/.local/lib/python3.7/site-packages/scrapy/core/spidermw.py", line 64, in _evaluate_iterable

for r in iterable:

TypeError: 'ItemMeta' object is not iterable`
 

Заранее благодарю вас и дайте мне знать, как улучшить ясность и качество моих вопросов.

Люк

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

1. Пожалуйста, покажите полное сообщение об ошибке, включая трассировку стека.

Ответ №1:

Вы возвращаете не элемент, вы возвращаете объект класса item.
Scrapy пытается повторить его, когда он возвращается из spider, так что вы получаете свое TypeError .

Простое исправление последней строки return item должно исправить ваш код.

В качестве примечания, scrapy имеет свои собственные утилиты синтаксического анализа, поэтому нет необходимости импортировать и использовать BS.

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

1. Большое вам спасибо за вашу помощь. Я рад видеть, что моя ошибка была такой простой. Теперь это работает хорошо. Что касается утилит синтаксического анализа, вы говорите об использовании xpath и css?

Ответ №2:

согласно ответу @stranac, я исправил полный код и его работу.

 import scrapy
from bs4 import BeautifulSoup

class PostscrapeItem(scrapy.Item):
    full_text = scrapy.Field()


class PostSpider(scrapy.Spider):
    name = "posts"

    start_urls = [
        'https://blog.scrapinghub.com/page/1/'
    ]

    def parse(self, response):
        so = BeautifulSoup(response.text, 'html.parser')
        item = PostscrapeItem()

        if so.find('em'):
            concatenated = ""
            text_samples = so.find_all('em')

            for t_s in text_samples:
                concatenated  = t_s.text

            item['full_text'] = concatenated

        return item
 

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

1. Спасибо за вашу быструю реакцию. Это для того, чтобы увидеть увлеченных людей, которые всегда готовы что-то попробовать. У меня это тоже работает.

2. Рад помочь. Спасибо