V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
iray1991
V2EX  ›  问与答

使用Calibre将期刊博客文章制作成电子书时,如何去掉抓取文章时间(365天)和篇数(100)的限制呢?

  •  
  •   iray1991 · 2012-01-31 16:29:48 +08:00 · 7190 次点击
    这是一个创建于 4679 天前的主题,其中的信息可能已经有所发展或是发生改变。
    介绍:
    http://www.quhuashuai.com/2010/10/fetch-news-in-calibre/

    方法:
    http://manual.calibre-ebook.com/news.html

    缺憾是RSS只能抓取一年以内且100篇以内,可否提取这个功能出来后去掉这个限制呢?
    18 条回复    1970-01-01 08:00:00 +08:00
    iray1991
        1
    iray1991  
    OP
       2012-01-31 19:21:34 +08:00
    切换到高级模式后显示:

    class AdvancedUserRecipe1327999270(BasicNewsRecipe):
    title = u'\u4f59\u665f'
    oldest_article = 365
    max_articles_per_feed = 100
    auto_cleanup = True

    feeds = [(u'\u4f59\u665f', u'http://www.luanxiang.org/blog/feed')]

    我直接修改为:

    class AdvancedUserRecipe1327999270(BasicNewsRecipe):
    title = u'\u4f59\u665f'
    oldest_article = 10000
    max_articles_per_feed = 10000
    auto_cleanup = True

    feeds = [(u'\u4f59\u665f', u'http://www.luanxiang.org/blog/feed')]

    结果显示:error

    sigh~这是肿么回事?
    iray1991
        2
    iray1991  
    OP
       2012-01-31 20:15:45 +08:00
    给开发者发了客服,刚收到回复:
    calibre can fetch only as many articles as are present in the feed iteself.
    That is seldom more than a year's worth.

    status invalid

    ** Changed in: calibre
    Status: New => Invalid

    --
    You received this bug notification because you are subscribed to the bug
    report.
    https://bugs.launchpad.net/bugs/924190

    Title:
    rss fetch number limited

    Status in calibre: e-book management:
    Invalid

    Bug description:
    the time of the feed is limited to 365 Day and I can get no more than 100 articles
    can't I fetch longer and more articles?
    Thx
    0.8.34
    win7
    lifanxi
        3
    lifanxi  
       2012-02-01 15:02:06 +08:00
    我曾经过试过你说的直接改oldest_article和max_articles_per_feed的方法,是可以达到期望的结果的。今天试了一下也没有能重现你的问题。

    你能描述一下你所遇到的“Error”是什么吗?

    另外,在用calibre新闻抓取功能时,要注意是不是受到了墙的干扰,尤其是抓国外的一些Feed或Google Reader时。
    iray1991
        4
    iray1991  
    OP
       2012-02-01 17:11:50 +08:00
    @lifanxi
    错误是显示在抓取的epub中的,显示:
    <urlopen error [Errno 10060] >

    检查了一下,确实有个feed是墙外的,无法输出:
    但是对于两个墙内的feed:
    http://www.luanxiang.org/blog/feed
    http://www.write.org.cn/feed
    当我修改这两个数值的时候也出现了同样的错误

    根据你的回复我又试了一下一个墙内可见的,增大两个值都到10000:
    http://www.zhihu.com/rss

    这次没有出现以上错误,但是无论我如何增大那两个数值,最后输出的epub的内容都是一样的,似乎更改这两个值的最大值并没有效果;

    你那边呢?能说说你的测试内容和修改内容,我这边再试试看
    我的软件版本是0.8.34,是否需要升级?
    lifanxi
        5
    lifanxi  
       2012-02-02 09:06:15 +08:00
    http://www.luanxiang.org/blog/feed 这个是墙外的,会跳转到被墙的feedburner上,所以很可能抓取不成功。
    http://www.write.org.cn/feed 访问有时候不流畅,会出错。如果流畅的话是可以的,改oldest_article明显是有效果的。
    http://www.zhihu.com/rss 上内容比较新,所以默认就可以抓全。把参数再改大也没有用,还是抓这么多。请注意Kovid给你回复中说的:calibre can fetch only as many articles as are present in the feed iteself. 如果RSS本身没有足够老的输出,你再改oldest_article也没有用。
    iray1991
        6
    iray1991  
    OP
       2012-02-02 09:09:31 +08:00
    @lifanxi
    calibre can fetch only as many articles as are present in the feed iteself.
    如果RSS本身没有足够老的输出,你再改oldest_article也没有用。

    意思是只能抓取更新的部分?(因为这个feed在GR里拉取的话是可以拉取到500+的,包括之前看过的部分,但是calibre只能拉取10+)
    iray1991
        7
    iray1991  
    OP
       2012-02-02 11:07:28 +08:00
    @iray1991 不知是否有可能写个豆瓣插件的?自动关联书库链接和评分之类。。
    lifanxi
        8
    lifanxi  
       2012-02-02 11:18:45 +08:00
    @iray1991
    每个网站的RSS输出量都是非常有限的,一般就限在几十条的量级,这个输出量是网站方控制的。calibre如果直接抓网站的RSS的话,就最多只能抓到这么多。

    如果某个网站的RSS在Google Reader中被某个人订阅过,那Google Reader的保存这个RSS所有的历史记录,即使网站实际输出的RSS中已经去掉了过期的内容,这些内容仍然会在Google Reader中保留。

    所以如果你真要抓全,那就不能从原始网站的RSS去抓,可以考虑通过Google Reader代理一层。这个好像没有办法直接实现,不过应该可以通过修改calibre中的Google Reader新闻抓取清单来实现。我有空可以试试看。
    lifanxi
        9
    lifanxi  
       2012-02-02 11:20:20 +08:00
    @iray1991
    豆瓣插件元信息下载插件不是老早就有了么?calibre安装时选中文界面时会自动启用。也可以在首选项->插件中手工启用。
    lifanxi
        10
    lifanxi  
       2012-02-02 13:42:57 +08:00
    改了一个Recepie,可以通过Google Reader下载所有的历史文章。

    先修改下面代码中的rssFeeds=['http://www.freemindworld.com/blog/feed.rss']'中的RSS地址,改成你想要的。如果有多个,可以用引号逗号隔开。比如:

    rssFeeds=['http://www.luanxiang.org/blog/feed','http://www.write.org.cn/feed']

    需要的话可以改一下max_articles_per_feed和oldest_article值,也许现在的默认值太大,会抓到太多的文章。

    把改好的代码直接贴到自定义订阅清单的高级模式中即可。

    在下载前,还要在"定期新闻下载"对话框中该订阅清单的"日程表"中输入你的Google帐号和密码。

    然后就可以点“立即下载”按钮了。

    注意,用这个订阅清单(包括别的所有needs_subscription = True的订阅清单)时,在下载任务的日志中会明文输出你输入的帐户和密码,所以如果要把日志往外帖的时候,注意把这些敏感信息清除掉。


    import urllib, re, mechanize
    from calibre.web.feeds.recipes import BasicNewsRecipe
    from calibre import __appname__

    class FullFeedViaGoogleReader(BasicNewsRecipe):
    title = 'Full Feed Via Google Reader'
    description = 'Fetches full feed articles from Google Reader'
    needs_subscription = True
    __author__ = 'davec, rollercoaster, Starson17, lifanxi'
    base_url = 'https://www.google.com/reader/atom/feed/'
    oldest_article = 10000
    max_articles_per_feed = 10000
    use_embedded_content = True

    def get_browser(self):
    br = BasicNewsRecipe.get_browser(self)
    if self.username is not None and self.password is not None:
    request = urllib.urlencode([('Email', self.username), ('Passwd', self.password),
    ('service', 'reader'), ('accountType', 'HOSTED_OR_GOOGLE'), ('source', __appname__)])
    response = br.open('https://www.google.com/accounts/ClientLogin', request)
    auth = re.search('Auth=(\S*)', response.read()).group(1)
    cookies = mechanize.CookieJar()
    br = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
    br.addheaders = [('Authorization', 'GoogleLogin auth='+auth)]
    return br

    def get_feeds(self):
    rssFeeds = ['http://www.freemindworld.com/blog/feed.rss']
    feeds = [ self.base_url + f + ('?n=%d' % self.max_articles_per_feed) for f in rssFeeds ]
    return feeds
    lifanxi
        11
    lifanxi  
       2012-02-02 13:50:57 +08:00
    代码帖过来缩进都没有了...请从下面的地址重新获取代码:
    http://www.freemindworld.com/tmp/fullfeed.txt
    iray1991
        12
    iray1991  
    OP
       2012-02-04 08:51:08 +08:00
    @lifanxi

    done:)
    还有一些小问题:

    1
    因为是通过https的GR抓取,是否意味着可以抓取墙外的内容?

    2
    对于某些feed,如http://www.shu0.net/?feed=rss2,当我采用传统抓取方法(即不使用recipe)时抓取内容正常.

    但是使用上面的recipe后,则显示:

    Failed feed: https://www.google.com/reader/atom/feed/http://www.shu0.net/?feed=rss2?n=10000

    HTTP Error 404: Not Found


    recipe如下:

    import urllib, re, mechanize
    from calibre.web.feeds.recipes import BasicNewsRecipe
    from calibre import __appname__

    class FullFeedViaGoogleReader(BasicNewsRecipe):
    title = 'Full Feed Via Google Reader 2'
    description = 'Fetches full feed articles from Google Reader'
    needs_subscription = True
    __author__ = 'davec, rollercoaster, Starson17, lifanxi'
    base_url = 'https://www.google.com/reader/atom/feed/'
    oldest_article = 10000
    max_articles_per_feed = 10000
    use_embedded_content = True

    def get_browser(self):
    br = BasicNewsRecipe.get_browser(self)
    if self.username is not None and self.password is not None:
    request = urllib.urlencode([('Email', self.username), ('Passwd', self.password),
    ('service', 'reader'), ('accountType', 'HOSTED_OR_GOOGLE'), ('source', __appname__)])
    response = br.open('https://www.google.com/accounts/ClientLogin', request)
    auth = re.search('Auth=(\S*)', response.read()).group(1)
    cookies = mechanize.CookieJar()
    br = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
    br.addheaders = [('Authorization', 'GoogleLogin auth='+auth)]
    return br

    def get_feeds(self):
    rssFeeds = ['http://www.shu0.net/?feed=rss2']
    feeds = [ self.base_url + f + ('?n=%d' % self.max_articles_per_feed) for f in rssFeeds ]
    return feeds)
    非常感谢你的解答!
    lifanxi
        13
    lifanxi  
       2012-02-04 15:15:09 +08:00
    @iray1991

    如果feed的URL中有“?”的话,要替换成%3F。
    > rssFeeds = ['http://www.shu0.net/%3Ffeed=rss2']

    用https确实可以解决一部分墙的问题,不过在这个使用场景下没有太大的用处。因为calibre在抓RSS时,是忽略RSS中嵌入的正文的,它是直接跟据RSS中的link去原始网站抓页面内容的,所以那里的link如果被墙,那就还是抓不下来。我一直想改个recipe直接采集RSS的正文,不过还没搞。另外,Google本身的https访问也并不是非常稳定的。所以,还是用VPN或代理比较靠谱。
    iray1991
        14
    iray1991  
    OP
       2012-02-06 12:53:35 +08:00
    @lifanxi
    或许能通过instapaper,readitlater或是klip.me这类的服务能够实现全文?
    see:
    1 http://www.mobileread.com/forums/showthread.php?t=143343&highlight=instapaper
    (这个有篇数限制,修改max值无效,是feed自身的限制吧?
    2 http://www.mobileread.com/forums/showthread.php?t=166089
    (这个登录有问题,我找不到登陆信息输入口,能指点一下?)
    PS:
    1 如果我想同时下载两个以上的feed应该在哪里修改订阅清单名称呢?(不大喜欢喜欢将几个feed加入同一个清单,这样只能依次下载;同时几个清单下载会快一点)
    2 通过GR这个recipe的话,公网下下载很慢,我用了Goagent代理后速度也快不起来,有解决方法吗?VPN或者换一个响应GR更快的DNS?
    lifanxi
        15
    lifanxi  
       2012-02-06 22:19:52 +08:00
    @iray1991
    1. 我也不知道,我不用Instapaper,注册了扔了几个页面进去抓了下好像没问题。抓到的文章应该跟http://www.instapaper.com/u这个页面上显示出来的文章数一样,与RSS无关。
    2.我试了User,Name,PIN和Google密码的各种组合,好像都不成功。我也不知道该怎么办了...这个网站是用Google的OAuth的,不知道如果做Basic Auth时应该用什么信息做验证。

    PS.
    1. title = 'Full Feed Via Google Reader 2'
    把这个改了就行
    2. 这个完全跟你访问Google以及RSS源中的网站的速度有关,跟软件无关。goagent不快的话你是可以考虑换vpn试试,反正只要你总体的网速越快越好。正常情况下,DNS在这个过程中对速度的影响应该不会占到主导因素。
    akax
        16
    akax  
       2012-04-19 22:25:22 +08:00
    @lifanxi 谢谢提供这些资料 我正想找个工具把GoogleReader导出来,这下一举两得 还做成了电子书 。上面的rss地址里的"http://"必须写成“http%3A%2F%2F”,还有这个方法应该能导出GR离得一个文件夹么?
    iray1991
        17
    iray1991  
    OP
       2012-04-20 11:29:48 +08:00
    @akax 下载后可以共享出来:)
    我这边网速很慢,使用加密连接后就更慢了:(
    akax
        18
    akax  
       2012-04-20 11:57:31 +08:00 via Android
    @iray1991 速度还可以接受 应该是制作epub过程比较耗时间吧 我是学校的2M网
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5235 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 08:52 · PVG 16:52 · LAX 00:52 · JFK 03:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.