解决Pocket部分文章无法在KOBO中看到的问题

开始

  虽然KOBO电纸书不能像Kindle那样那么方便的进行推送,但是它原生支持Pocket(稍后阅读)是很有用的,甚至可以通过配合IFTTT来实现很多Kindle无法实现的推送。

  于是现在看到一些长文,为了防止眼睛疲劳,都收入Pocket里面再用KOBO来阅读。然而后面我发现,有很多在Pocket列表里面的文章并没有被同步到KOBO上,所以想着要怎样去解决这个问题。

KOBO同步列表 Pocket文章列表

  如图所示,一些在Pocket列表里面的,却没能同步到KOBO的列表里面。

寻因

  首先我Pocket列表里面的文章大部分都是知乎专栏的文章,由于有的能推送有的不能推送,所以我一直认为是Pocket服务或者是KOBO本身的问题。直到今天,lywn123_提醒我实际上是知乎专栏的问题,并且给出这个问题链接。虽然这个问题下面没有给出方案,但是至少让我锁定了原因——知乎。

  Pocket收藏的文章分两种的,有些是Pocket提取出来,在Pocket下点击之后进入Pocket的Read界面浏览的;有的是无法分析页面内容,只能记录网址,在Pocket列表中点开是跳转网址的。这两种收藏中只有前者是能够被KOBO接受推送的,而知乎专栏对Pocket的爬取并不友好,这就造成了有些文章无法推送的情况。

解决

曲线救国

  知道原因就好办了,因为之前做爬虫的时候印象中知乎专栏是提供一个API的,比如某个专栏文章地址是 https://zhuanlan.zhihu.com/p/26756186 ,通过API来读取是在 https://zhuanlan.zhihu.com/api/posts/26756186 这里,直接浏览器打开API是一片看不懂的纯文本,实际上这是JSON格式的文章内容,整理一下格式是这样。

整理完的JSON

  从图上可以看到基本上专栏页面上所有需要的内容都在这个API里面了。这样可以采用一个曲线救国的办法,先写一个 php 的爬虫从知乎专栏的API中抓取所需的文章,然后把抓取到的存入 Pocket 就行了。

  网上已经有大神写过这个爬虫了[1],代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
if (!isset($_GET["page"])) {
echo "need page id.";
exit;
}
$PAGE_ID = $_GET["page"];
$P_HEADERS = getallheaders();
if (array_key_exists("Referer", $P_HEADERS) || (isset($_GET["redirect"]) && $_GET["redirect"] == '1')) {
header("Location: https://zhuanlan.zhihu.com/p/" . $PAGE_ID);
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta name="referrer" content="never"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<?php
$PAGE_DATA = file_get_contents("https://zhuanlan.zhihu.com/api/posts/" . $PAGE_ID);
$PAGE_OBJ = json_decode($PAGE_DATA);
echo '<title>' . $PAGE_OBJ->{"title"} . '</title>';
?>
<link rel="shortcut icon" href="https://static.zhihu.com/static/favicon.ico" type="image/x-icon">
</head>
<body>
<h1>
<?php
echo $PAGE_OBJ->{"title"};
?>
</h1>
<div>
<?php
echo $PAGE_OBJ->{"content"};
?>
<div>
</body>
</html>

  把它放入 php 服务器后访问它并传入文章ID到 page 变量即可,比如 http://o.candura.us/zhihu.php?page=26756186 ,再将这个链接抓到Pocket中就行了。

Nginx 之惑

  本来正常来说这样就全部解决了,但是这个 php 爬虫在我的服务器中并不能正常运行。后面用探针一个个函数测试,发现是我的服务器并不支持getallheaders函数。

函数检测

  后来才想起,我的服务器环境是用 Nginx 构建的,并不是用 Apache,而getallheaders函数虽然是 php 的函数,但是是apache_request_headers函数的别名,无怪乎其无法用在 Nginx 下。

  后来在《PHP Manual》中找到这个函数原型[2],把它加入到上面那个 php 爬虫里就真的OK了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
if (!function_exists('getallheaders'))
{
function getallheaders()
{
$headers = '';
foreach ($_SERVER as $name => $value)
{
if (substr($name, 0, 5) == 'HTTP_')
{
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}
}
?>

成型

  将最终的完整代码放入服务器上访问就搞定了。

  最终,这样加入Pocket的文章成功的同步到KOBO上了。

最终同步效果

参考资料

1.简单PHP实现Pocket抓取知乎专栏文章

2.PHP: getallheaders - Manual

文章目录
  1. 1. 开始
  2. 2. 寻因
  3. 3. 解决
    1. 3.1. 曲线救国
    2. 3.2. Nginx 之惑
    3. 3.3. 成型
  4. 4. 参考资料
|