我的scrapy脚本似乎不遵循链接,最终导致它们没有从每个链接中提取数据(将某些内容作为scrapy items
传递)。
我正试图从新闻网站上抓取很多数据。如我所料,我设法复制/编写了一个蜘蛛,应该从文件中读取链接(我已经用另一个脚本生成了该链接),将它们放在start_urls
列表中,然后开始按照这些链接提取一些数据,然后将其作为items
传递,并且-将每个项目的数据写入一个单独的文件中(最后一部分实际上是针对另一个问题)。
运行scrapy crawl PNS
后,脚本会遍历start_urls
中的所有链接,但无所事事–它遵循从start_urls
列表中读取的链接(我收到“ GET link”消息在bash中),但似乎没有输入它们,而是阅读了一些其他链接来跟踪和提取数据。
import scrapy
import re
from ProjectName.items import ProjectNameArticle
class ProjectNameSpider(scrapy.Spider):
name = 'PNS'
allowed_domains = ['www.project-domain.com']
start_urls = []
with open('start_urls.txt', 'r') as file:
for line in file:
start_urls.append(line.strip())
def parse(self, response):
for link in response.css('div.news-wrapper_ h3.b-item__title a').xpath('@href').extract():
# extracted links look like this: "/document.html"
link = "https://project-domain.com" + link
yield scrapy.Request(link, callback=self.parse_news)
def parse_news(self, response):
data_dic = ProjectNameArticle()
data_dic['article_date'] = response.css('div.article__date::text').extract_first().strip()
data_dic['article_time'] = response.css('span.article__time::text').extract_first().strip()
data_dic['article_title'] = response.css('h3.article__title::text').extract_first().strip()
news_text = response.css('div.article__text').extract_first()
news_text = re.sub(r'(<script(\s|\S)*?<\/script>)|(<style(\s|\S)*?<\/style>)|(<!--(\s|\S)*?-->)|(<\/?(\s|\S)*?>)', '', news_text).strip()
data_dic['article_text'] = news_text
return data_dic
预期结果:
- 脚本打开start_urls.txt文件,读取其行(每行包含一个链接),并将这些链接放入
start_urls
列表中,- 对于每个打开的蜘蛛,spider提取要遵循的更深层链接(每个
start_urls
链接大约50-200个链接),- 以下链接是我要从中提取特定数据的主要目标:文章标题,日期,时间,文本。
- 目前,不必介意将每个拼凑项目写入distinc .txt文件。
实际结果:
- 运行蜘蛛会为每个
start_urls
链接触发GET,经过大约150000次,不会创建更深层链接的列表,也不会输入它们来提取任何数据。
答案 0 :(得分:3)
Dude,我使用Python Scrapy编写代码已有很长时间了,我讨厌使用start_urls
您可以简单地使用start_requests
,它很容易阅读,对于初学者也很容易学习
class ProjectNameSpider(scrapy.Spider):
name = 'PNS'
allowed_domains = ['www.project-domain.com']
def start_requests(self):
with open('start_urls.txt', 'r') as file:
for line in file:
yield Request(line.strip(),
callback=self.my_callback_func)
def my_callback_func(self, response):
for link in response.css('div.news-wrapper_ h3.b-item__title a').xpath('@href').extract():
# extracted links look like this: "/document.html"
link = "https://project-domain.com" + link
yield scrapy.Request(link, callback=self.parse_news)
def parse_news(self, response):
data_dic = ProjectNameArticle()
data_dic['article_date'] = response.css('div.article__date::text').extract_first().strip()
data_dic['article_time'] = response.css('span.article__time::text').extract_first().strip()
data_dic['article_title'] = response.css('h3.article__title::text').extract_first().strip()
news_text = response.css('div.article__text').extract_first()
news_text = re.sub(r'(<script(\s|\S)*?<\/script>)|(<style(\s|\S)*?<\/style>)|(<!--(\s|\S)*?-->)|(<\/?(\s|\S)*?>)', '', news_text).strip()
data_dic['article_text'] = news_text
return data_dic
我也从未使用过Item
类,也发现它没用
您只需拥有data_dic = {}
而不是data_dic = ProjectNameArticle()