Scrapy Spider不返回任何商品数据

时间:2019-01-29 14:35:57

标签: python-3.x scrapy scrapy-spider

我的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

预期结果:

  
      
  1. 脚本打开start_urls.txt文件,读取其行(每行包含一个链接),并将这些链接放入start_urls列表中,
  2.   
  3. 对于每个打开的蜘蛛,spider提取要遵循的更深层链接(每个start_urls链接大约50-200个链接),
  4.   
  5. 以下链接是我要从中提取特定数据的主要目标:文章标题,日期,时间,文本。
  6.   
  7. 目前,不必介意将每个拼凑项目写入distinc .txt文件。
  8.   

实际结果:

  
      
  1. 运行蜘蛛会为每个start_urls链接触发GET,经过大约150000次,不会创建更深层链接的列表,也不会输入它们来提取任何数据。
  2.   

1 个答案:

答案 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()