#python #scrapy
#питон #scrapy
Вопрос:
У меня странная проблема, связанная с Scrapy. Я следовал руководству по обходу ссылок, но по какой-то причине ничего не происходит.
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from bs4 import BeautifulSoup
import pandas as pd
from time import strftime
class Covid_Crawler(scrapy.Spider):
name = "Covid_Crawler"
allowed_domains = ['worldometers.info/coronavirus/']
start_urls = ['https://www.worldometers.info/coronavirus/countries-where-coronavirus-has-spread/']
def parse(self, response):
count = 0
soup = BeautifulSoup(response.text, "lxml")
try:
covid_table = soup.find('table')
df = pd.read_html(str(covid_table))[0]
print(df)
df.to_csv("CovidFile.csv",index=False)
except:
print("Table not found")
NEXT_PAGE_SELECTOR = 'a::attr(href)'
next_page = response.css(NEXT_PAGE_SELECTOR).getall()
if next_page is not None:
yield response.follow(next_page, callback=self.parse)
По какой-то причине, когда я пытаюсь запустить этот паук, он отлично захватывает таблицу с первой страницы. Но он не хочет переходить к другим ссылкам. Когда я запускаю его, я получаю что-то вроде этого.
2020-12-12 20:45:15 [scrapy.core.engine] DEBUG: Crawled (200) <GET
https://www.worldometers.info/coronavirus/countries-where-coronavirus-has-spread/> (referer: None)
2020-12-12 20:45:15 [numexpr.utils] INFO: NumExpr defaulting to 6 threads.
Country Cases Deaths Region
0 United States 16549366 305082 North America
1 India 9857380 143055 Asia
2 Brazil 6880595 181143 South America
3 Russia 2625848 46453 Europe
4 France 2365319 57761 Europe
.. ... ... ... ...
214 MS Zaandam 9 2 NaN
215 Marshall Islands 4 0 Australia/Oceania
216 Wallis amp; Futuna 3 0 Australia/Oceania
217 Samoa 2 0 Australia/Oceania
218 Vanuatu 1 0 Australia/Oceania
[219 rows x 4 columns]
2020-12-12 20:45:15 [scrapy.core.scraper] ERROR: Spider error processing <GET
https://www.worldometers.info/coronavirus/countries-where-coronavirus-has-spread/> (referer: None)
Traceback (most recent call last):
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyutilsdefer.py", line 120, in iter_errback
yield next(it)
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyutilspython.py", line 353, in __next__
return next(self.data)
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyutilspython.py", line 353, in __next__
return next(self.data)
File "C:UsersZach Kunzanaconda3libsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
for r in iterable:
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyspidermiddlewaresoffsite.py", line 29, in process_spider_output
for x in result:
File "C:UsersZach Kunzanaconda3libsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
for r in iterable:
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyspidermiddlewaresreferer.py", line 340, in <genexpr>
return (_set_referer(r) for r in result or ())
File "C:UsersZach Kunzanaconda3libsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
for r in iterable:
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyspidermiddlewaresurllength.py", line 37, in <genexpr>
return (r for r in result or () if _filter(r))
File "C:UsersZach Kunzanaconda3libsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
for r in iterable:
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyspidermiddlewaresdepth.py", line 58, in <genexpr>
return (r for r in result or () if _filter(r))
File "C:UsersZach Kunzanaconda3libsite-packagesscrapycorespidermw.py", line 62, in _evaluate_iterable
for r in iterable:
File "C:UsersZach KunzDocumentsCrawler_TestCovid_CrawlerCovid_CrawlerspidersCrawler_spider.py", line 84, in parse
yield response.follow(next_page, callback=self.parse)
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyhttpresponsetext.py", line 169, in follow
return super().follow(
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyhttpresponse__init__.py", line 143, in follow
url = self.urljoin(url)
File "C:UsersZach Kunzanaconda3libsite-packagesscrapyhttpresponsetext.py", line 102, in urljoin
return urljoin(get_base_url(self), url)
File "C:UsersZach Kunzanaconda3liburllibparse.py", line 512, in urljoin
base, url, _coerce_result = _coerce_args(base, url)
File "C:UsersZach Kunzanaconda3liburllibparse.py", line 121, in _coerce_args
raise TypeError("Cannot mix str and non-str arguments")
TypeError: Cannot mix str and non-str arguments
2020-12-12 20:45:15 [scrapy.core.engine] INFO: Closing spider (finished)
И используя оболочку scrapy, чтобы проверить, получает ли она ссылки, я получаю это
In [6]: response.css('a::attr(href)').getall()
Out[6]:
['/',
'/coronavirus/',
'/population/',
'/coronavirus/',
'/coronavirus/',
'/coronavirus/coronavirus-cases/',
'/coronavirus/worldwide-graphs/',
'/coronavirus/#countries',
'/coronavirus/coronavirus-death-rate/',
'/coronavirus/coronavirus-incubation-period/',
'/coronavirus/coronavirus-age-sex-demographics/',
'/coronavirus/coronavirus-symptoms/',
'/coronavirus/',
'/coronavirus/coronavirus-death-toll/',
'/coronavirus/#countries',
'/coronavirus/',
'/coronavirus/coronavirus-cases/',
'/coronavirus/coronavirus-death-toll/',
'/coronavirus/coronavirus-death-rate/',
'/coronavirus/coronavirus-incubation-period/',
'/coronavirus/coronavirus-age-sex-demographics/',
'/coronavirus/coronavirus-symptoms/',
'/coronavirus/countries-where-coronavirus-has-spread/',
'/coronavirus/#countries',
'/',
'/about/',
'/faq/',
'/languages/',
'/contact/',
'/newsletter-subscribe/',
'https://twitter.com/Worldometers',
'https://www.facebook.com/Worldometers.info',
'/disclaimer/']
Любая помощь или понимание будут высоко оценены. И если вы готовы помочь с другой проблемой, я ищу решение для хранения всех диаграмм, которые я собираю, в нескольких файлах csv или xlsx. Спасибо!
Ответ №1:
response.follow()
не могу работать с а list
. Вам нужно указать один строковый аргумент:
next_pages = response.css(NEXT_PAGE_SELECTOR).getall()
for next_page in next_pages:
if next_page is not None:
yield response.follow(next_page, callback=self.parse)
Комментарии:
1. Это действительно работает, спасибо! Единственная проблема заключается в том, что, похоже, он только захватывает ссылки с помощью http, в котором нет того, что я хочу. Как это будет работать для ссылок, которые просто имеют расширение к нему?
2. Неважно, я понял это. Спасибо за помощь!
Ответ №2:
Вы могли бы использовать yield from response.follow_all(next_pages)
which, который делал бы то же самое, что и то, что опубликовал gangabass.