暗无天日

=============>DarkSun的个人博客

一个显示中文格言的fortune文件

我一直觉得fortune挺好玩的,最近刚好在学习python,就试着用python写了一个小东西用来从baidu中抓取格言,写成fortune文件.

fortune文件可以从这里下载:proverbs

使用方法

  1. 要让fortune能够使用该fortune文件,还需要先用 strfile 来产生一个索引文件 proverbs.dat

    strfile proverbs
    
    "proverbs.dat" created
    There were 760 strings
    Longest string: 313 bytes
    Shortest string: 28 bytes
    
  2. 要将该fortune文件安装到fortune数据库中,只需要将将fortune文件和生成的索引文件一起拷贝到fortune存储数据文件的目录中就行了

    sudo cp proverbs proverbs.dat /usr/share/fortune
    

    注意:fortune数据存放目录在不同linux发行版上可能不同,具体是在哪,请执行 man fortune 查看

  3. 如果你不想污染原始的fortune数据库,或者没有root权限,fortune也可以用命令行参数直接指定读取的文件:

    fortune proverbs
    

实现

数据来源

为了搜索格言,我先尝试在baidu上搜索了一下"格言",结果发现baidu除了显示出相关网页链接之外,还显示了一个小窗口里面列出了大量的格言:

点击其中的1,2,3页,发现访问的URL分别是

https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?from_mid=1&format=json&ie=utf-8&oe=utf-8&subtitle=格言&query=格言&rn=8&pn=0&resource_id=6844&cb=jQuery110208193217330929087_1488263284684&_=1488263284688

https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?from_mid=1&format=json&ie=utf-8&oe=utf-8&subtitle=格言&query=格言&rn=8&pn=8&resource_id=6844&cb=jQuery110208193217330929087_1488263284684&_=1488263284686

https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?from_mid=1&format=json&ie=utf-8&oe=utf-8&subtitle=格言&query=格言&rn=8&pn=16&resource_id=6844&cb=jQuery110208193217330929087_1488263284684&_=1488263284687

URL中的 %E6%A0%BC%E8%A8%80 就是格言的转义结果.

通过对比这些访问的URL不难推测出其中的参数 rn 应该是每次返回的格言条数, pn 应该指定从第几条格言开始显示.

后面参数 _ 的值虽然在不断的改变,好在经过实验发现这个参数不传递也不会影响结果. 事实上,你还能够把 cb 参数也一起省略掉.

另外,经过实验发现 rn 的最大值只能是50,超过50的值返回的结果依然只有50条格言.

分析出接口地址,再从JSON结果中抓取相应的值就很容易了:

def request_proverb(start,number):
    '''从百度那获取格言信息,START为起始条数,NUMBER为获取格言条数,不能超过50'''
    url = "https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php"
    params = {"from_mid":1,
              "format":"json",
              "ie":"utf-8",
              "oe":"utf-8",
              "subtitle":"格言",
              "query":"格言",
              "rn":number,
              "pn":start,
              "resource_id" : 6844}
    response = requests.get(url,params=params)
    response = json.loads(response.text)
    status = response.get('status')
    if status != "0":
        raise Exception()
    data = response.get('data')[0]
    resNum = data.get('resNum')
    proverbs = data.get('disp_data')
    return proverbs

其中,每个格言信息都是一个如下所示的字典:

{'StdStg': 6844, 'StdStl': 8, '_update_time': '1475048807', 'loc': 'http://www.baidu.com/geyan/c880b7476531e5cbf050dce6da74578c', 'lastmod': '2014-06-26', 'changefreq': 'always', 'priority': '1.0', 'type': '格言', 'brief0': '真理,真谛', 'term0': '欧文', 'term': '欧文', 'ename': '真理惟一可靠的标准就是永远自相符合。', 'stat0': '真理', 'statctl': 'stat0', 'statlst': '类别', 'author': '欧文', 'pv': '59', 'SiteId': 2003651, '_version': 5, '_select_time': 1475048794}

不过我们只需要其中的 enameauthor 这两个信息.

fortune文件格式

fortune文件格式蛮简单的,只需要用 只包含%的行 将各格言内容分开就行了.

每条格言,我希望显示成 格言的内容 后面跟一个横杠,再跟上 作者 这样.

真理惟一可靠的标准就是永远自相符合。
	-欧文
%
土地是以它的肥沃和收获而被估价的;才能也是土地,不过它生产的不是粮食,而是真理。如果只能滋生瞑想和幻想的话,即使再大的才能也只是砂地或盐池,那上面连小草也长不出来的。
	-别林斯基

使用字符串的 format 方法可以很容易的控制生成的格言格式

def proverb_to_fortune_item(proverb):
    author = proverb.get('author','')
    ename = proverb.get('ename','')
    return "{ename}\n\t-{author}\n".format(ename=ename,author=author)

最后再用 "%\n" 作为分隔符将每条格言拼接起来就完成了

def proverbs_to_fortune_file(proverbs,fortune_file):
    with open(fortune_file,mode="a") as f:
        fortune_items = [proverb_to_fortune_item(proverb) for proverb in proverbs]
        f.write('%\n'.join(fortune_items))