#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. Рад помочь. Спасибо