Это следование по вопросу от Python Scrapy & YieldPython Scrapy и плодоношения
Я в настоящее время разрабатывает скребок с использованием Scrapy в первый раз, и я использую Выход в первый раз, а также. Я очень сильно смущен тем, как работает доходность.
скребковые:
- Царапина одна страницы, чтобы получить список диапазонов дат
- использует эти даты диапазонов форматировать URLS для затем соскрести другую страницу, которая содержит списки, которые разбиваются на страницах в группы из 10 списков
- Я бы хотел отменить все эти URL-адреса, которые ссылаются на 10 объявлений
Затем на этих страницах я хотел бы отказаться от всех списков и извлечь данные из них. Эти индивидуальные списки также содержат 4 «вкладки», которые необходимо очистить.
class MyScraper(scrapy.Spider): name = "myscraper" start_urls = [ ] def parse(self, response): rows = response.css('table.apas_tbl tr').extract() for row in rows[1:]: soup = BeautifulSoup(row, 'lxml') url = soup.find_all("a")[1]['href'] yield scrapy.Request(url, callback=self.parse_page_contents) def parse_page_contents(self, response): rows = response.xpath('//div[@id="apas_form"]').extract_first() soup = BeautifulSoup(rows, 'lxml') pages = soup.find(id='apas_form_text') for link in pages.find_all('a'): url = link['href'] yield scrapy.Request(url, callback=self.parse_page_listings) def parse_page_listings(self, response): rows = response.xpath('//div[@id="apas_form"]').extract_first() soup = BeautifulSoup(rows, 'lxml') resultTable = soup.find("table", { "class" : "apas_tbl" }) for row in resultTable.find_all('a'): url = row['href'] yield scrapy.Request(url, callback=self.parse_individual_listings) def parse_individual_listings(self, response): rows = response.xpath('//div[@id="apas_form"]').extract_first() soup = BeautifulSoup(rows, 'lxml') fields = soup.find_all('div',{'id':'fieldset_data'}) data = {} for field in fields: data[field.label.text.strip()] = field.p.text.strip() tabs = response.xpath('//div[@id="tabheader"]').extract_first() soup = BeautifulSoup(tabs, 'lxml') links = soup.find_all("a") for link in links: yield scrapy.Request( urlparse.urljoin(response.url, link['href']), callback=self.parse_individual_tabs, meta={'data': data} ) print data def parse_individual_tabs(self, response): data = {} rows = response.xpath('//div[@id="tabContent"]').extract_first() soup = BeautifulSoup(rows, 'lxml') fields = soup.find_all('div',{'id':'fieldset_data'}) for field in fields: data[field.label.text.strip()] = field.p.text.strip() yield json.dumps(data)
Скребок в настоящее время, кажется, немного работы с проблемами, хотя. Основная проблема на данный момент:
ERROR: Spider must return Request, BaseItem, dict or None, got 'str' in
также существует некоторое дублирование URL-адресов, которые очищаются. Мне интересно (а), что вызывает вышеприведенную ошибку, и (б) правильно ли форматируется выходная настройка?
Вам не обязательно, чтобы вы se 'yield': вы можете просто построить список, в котором вы храните все элементы' yield'ed и возвращаете список. –
@WillemVanOnsem, пока вы правы, это более удобно и, как правило, лучше использовать значения 'yield' вместо того, чтобы хранить их во временном списке и затем возвращать весь список.Не только 'yield' выглядит лучше, но использование' yield' вместо 'return' превращает функцию в генератор, который работает лучше. – Granitosaurus
@ Granitosaurus: Да, я использую 'yield' все время (несмотря на то, что это единственное, что нравится в моей рабочей области). Это также лучше для памяти (скажем, вы испускаете миллион объектов, каждый из которых занимает несколько мегабайт, а список не может их хранить). Но в этом случае кривая обучения, вероятно, менее крутая при использовании списков. –