Scrapy-如何从类别中提取所有博客帖子?

时间:2015-09-28 08:32:04

标签: python regex wordpress scrapy scrapy-spider

我正在使用scrapy来提取我博客的所有帖子。问题是我无法弄清楚如何创建一个规则来读取任何给定博客类别中的所有帖子?

示例:在我的博客上,“环境设置”类别有17个帖子。所以在scrapy代码中我可以硬编码,但这不是一个非常实用的方法

start_urls=["https://edumine.wordpress.com/category/ide- configuration/environment-setup/","https://edumine.wordpress.com/category/ide-configuration/environment-setup/page/2/","https://edumine.wordpress.com/category/ide-configuration/environment-setup/page/3/"] 

我已阅读与此处发布的此问题相关的类似帖子,例如12345,{{3 } {},6,但我似乎无法找到答案。如您所见,唯一的区别是上面网址中的页数。如何在scrapy中编写可以读取类别中所有博客帖子的规则。另一个微不足道的问题是,我如何配置蜘蛛来抓取我的博客,这样当我发布新的博客文章时,抓取工具可以立即检测到它并将其写入文件。

这是我迄今为止的蜘蛛类

from BlogScraper.items import BlogscraperItem
from scrapy.spiders import CrawlSpider,Rule
from scrapy.selector import Selector
from scrapy.linkextractors import LinkExtractor
from scrapy.http import Request


class MySpider(CrawlSpider):
    name = "nextpage" # give your spider a unique name because it will be used for crawling the webpages

    #allowed domain restricts the spider crawling
    allowed_domains=["https://edumine.wordpress.com/"]
    # in start_urls you have to specify the urls to crawl from
    start_urls=["https://edumine.wordpress.com/category/ide-configuration/environment-setup/"]

    '''
    start_urls=["https://edumine.wordpress.com/category/ide-configuration/environment-setup/",
                "https://edumine.wordpress.com/category/ide-configuration/environment-setup/page/2/",
                "https://edumine.wordpress.com/category/ide-configuration/environment-setup/page/3/"]


    rules = [
                Rule(SgmlLinkExtractor
                    (allow=("https://edumine.wordpress.com/category/ide-configuration/environment-setup/\d"),unique=False,follow=True))
            ]
'''
    rules= Rule(LinkExtractor(allow='https://edumine.wordpress.com/category/ide-configuration/environment-setup/page/'),follow=True,callback='parse_page')

    def parse_page(self, response):

        hxs=Selector(response)
        titles = hxs.xpath("//h1[@class='entry-title']")
        items = []
        with open("itemLog.csv","w") as f:
             for title in titles:
                item = BlogscraperItem()
                item["post_title"] = title.xpath("//h1[@class='entry-title']//text()").extract()
                item["post_time"] = title.xpath("//time[@class='entry-date']//text()").extract()
                item["text"]=title.xpath("//p//text()").extract()
                item["link"] = title.select("a/@href").extract()

                items.append(item)

                f.write('post title: {0}\n, post_time: {1}\n, post_text: {2}\n'.format(item['post_title'], item['post_time'],item['text']))
                print "#### \tTotal number of posts= ",len(items), " in category####"


        f.close()

有任何帮助或建议可以解决吗?

1 个答案:

答案 0 :(得分:2)

您可以在代码中修改一些内容并解决两个问题:阅读帖子,自动抓取。

如果您想获取新博文的内容,则必须重新运行蜘蛛。否则你会有一个无限循环。当然,在这种情况下,您必须确保不刮掉已经删除的条目(数据库,在蜘蛛启动时读取可用文件等)。但你不能拥有永远运行的蜘蛛并等待新的条目。这不是目的。

将帖子存储到文件中的方法是错误的。这意味着你为什么要刮掉一个项目清单,然后对它们什么都不做?为什么要保存parse_page功能中的项目?为此,有item pipelines,你应该写一个并在那里进行导出。并且f.close()不是必需的,因为您使用最后为您执行此操作的with语句。

您的rules变量应该抛出错误,因为它不可迭代。我想知道你是否测试了你的代码。规则太复杂了。您可以将其简化为:

rules = [Rule(LinkExtractor(allow='page/*'), follow=True, callback='parse_page'),]

它跟随每个包含/page的网址。

如果您启动了刮刀,您会看到结果因您允许的域名而被过滤:

Filtered offsite request to 'edumine.wordpress.com': <GET https://edumine.wordpress.com/category/ide-configuration/environment-setup/page/2/>

要解决此问题,请将您的域名更改为:

allowed_domains = ["edumine.wordpress.com"]

如果您想获得其他wordpress网站,请将其更改为

allowed_domains = ["wordpress.com"]
相关问题