<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Soul Of Free Loop &#187; Python</title>
	<atom:link href="https://zohead.com/archives/category/technology/python/feed/" rel="self" type="application/rss+xml" />
	<link>https://zohead.com</link>
	<description>Uranus Zhou&#039;s Blog</description>
	<lastBuildDate>Sat, 19 Jul 2025 15:42:46 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.8</generator>
	<item>
		<title>Linux实现惠尔顿上网认证客户端</title>
		<link>https://zohead.com/archives/wholeton-linux-client/</link>
		<comments>https://zohead.com/archives/wholeton-linux-client/#comments</comments>
		<pubDate>Sun, 15 May 2022 03:34:10 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[WebSocket]]></category>
		<category><![CDATA[惠尔顿]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1745</guid>
		<description><![CDATA[最近公司由于某些特殊原因，需要上一套惠尔顿的上网行为管理系统，局域网内的所有设备在连接互联网时都需要通过惠尔顿上网认证客户端进行登录，或者需要管理员在上网行为管理中设置免监控。 惠尔顿官方只提供了 Windows 上的客户端进行用户登录，也可以访问网页版进行临时登录，效果如下： 不过 Linux 服务器设备就没法登录了，为此我写了个 Python 程序模拟惠尔顿的网页版客户端实现 Linux / macOS 等系统下的上网认证功能。 Python 程序 我编写的 wholeton-auth.py Python 程序可以通过 Pastebin 分享链接 下载，写的很简单粗糙，这里贴出来说明一下： [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>最近公司由于某些特殊原因，需要上一套惠尔顿的上网行为管理系统，局域网内的所有设备在连接互联网时都需要通过惠尔顿上网认证客户端进行登录，或者需要管理员在上网行为管理中设置免监控。</p>
<p>惠尔顿官方只提供了 Windows 上的客户端进行用户登录，也可以访问网页版进行临时登录，效果如下：</p>
<p><img src="https://images.weserv.nl/?url=http://res.cloudinary.com/digwht2y0/image/upload/v1737442965/wholeton-login.jpg" alt="惠尔顿上网认证系统网页版"></p>
<p>不过 Linux 服务器设备就没法登录了，为此我写了个 Python 程序模拟惠尔顿的网页版客户端实现 Linux / macOS 等系统下的上网认证功能。</p>
<h2 id="python-wholeton-client">Python 程序</h2>
<p>我编写的 <code>wholeton-auth.py</code> Python 程序可以通过 <a href="https://pastebin.com/raw/5XhfVS2S">Pastebin 分享链接</a> 下载，写的很简单粗糙，这里贴出来说明一下：</p>
<pre class="brush: python; highlight: [20,21,22,23,24,25]; title: ; notranslate">
#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import socket
from datetime import datetime
from uuid import getnode
import urllib
try:
    import urllib2
except Exception:
    from urllib import request as urllib2
try:
    import Cookie as cookies
except Exception:
    from http import cookies
import websocket
import json

wholeton_host = '192.168.1.254'
wholeton_user = 'test'
wholeton_pass = '123456'
wholeton_ip = ''
wholeton_mac = ''
update_secs = 28800

def url_encode(obj):
    try:
        return urllib.urlencode(obj)
    except Exception:
        return urllib.parse.urlencode(obj)

def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

def get_mac():
    return ':'.join((&quot;%012x&quot; % getnode())[i:i+2] for i in range(0, 12, 2))

if not wholeton_ip:
    wholeton_ip = get_ip()

if not wholeton_mac:
    wholeton_mac = get_mac()

uri_keys = { 'id' : 0, 'url' : 'mail.126.com', 'user' : wholeton_ip, 'mac' : wholeton_mac }
uri_data = url_encode(uri_keys).replace('%3A', ':')

auth_data = url_encode({ 'param[UserName]' : wholeton_user, 'param[UserPswd]' : wholeton_pass, 'uri' : uri_data, 'force' : 0 })
# convert for python 3
if sys.version_info[0] == 3:
    auth_data = auth_data.encode('ascii')

ws = None
loop = True

try:
    while loop:
        resp = urllib2.urlopen('http://' + wholeton_host + '/user-login-auth?' + uri_data, timeout = 5, data = auth_data)

        # get session cookie
        cookie = cookies.SimpleCookie()
        cookie.load(resp.info()['Set-Cookie'])

        resp_data = resp.read()
        if resp_data:
            print('Login response:')
            print(resp_data)

        ws = websocket.WebSocket()
        ws.connect('ws://' + wholeton_host + '/go-ws/user-auth', cookie = 'fms_session=' + cookie.get('fms_session').value, origin = 'http://' + wholeton_host)

        dt_start = datetime.now()
        while ws:
            try:
                ws_data = ws.recv()
            except KeyboardInterrupt:
                loop = False
                break
            except:
                break

            if ws_data:
                dt_now = datetime.now()
                if (dt_now - dt_start).seconds &gt;= update_secs:
                    break

                print(dt_now)
                print(ws_data)

                ws_obj = json.loads(ws_data)
                if ws_obj and ws_obj[&quot;type&quot;] == &quot;logged-out&quot;:
                    break

        if ws:
            ws.close()
        ws = None
except KeyboardInterrupt:
    pass

if ws:
    ws.close()
</pre>
<p>为了支持比较老的服务器系统，此 Python 程序同时支持 Python 2 和 Python 3，在 Python 2.6 和 Python 3.6 版本上做了测试。为了减少依赖，本程序基本都是用的 Python 自带的模块，并针对 Python 2 和 Python 3 进行了区分处理。</p>
<p>程序首先通过惠尔顿网页版的 HTTP 登录接口进行登录，登录成功之后获取会话信息，然后建立 WebSocket 连接，并保持 WebSocket 连接状态，如果关闭了连接上网认证功能就会自动失效。</p>
<p>由于本程序需要建立 WebSocket 连接，也不需要任何 WebSocket 服务器的功能，所以没有用各种功能齐全的 WebSocket 库，只额外使用了 <a href="https://pypi.org/project/websocket-client/">websocket-client</a> 这个非常简单的 WebSocket 客户端库。</p>
<p>另外最新 1.3.2 版本的 websocket-client 库只支持 Python 3.7 及以上版本，为了能给 Python 2.6 版本使用，本程序使用的是 websocket-client 老一点的 <a href="https://pypi.org/project/websocket-client/0.59.0/">0.59.0</a> 版本，websocket-client 0.59.0 版本支持 Python 2.6 以上或 Python 3.4 以上版本，而且只依赖 <a href="https://pypi.org/project/six/">six</a> 这个 Python 兼容库，同时 six 库也使用 <a href="https://pypi.org/project/six/1.13.0/">1.13.0</a> 版本以兼容 Python 2.6 版本。</p>
<p>可以使用 pip 命令先安装 six 1.13.0 版本和 websocket-client 0.59.0 版本：</p>
<pre class="brush: bash; title: ; notranslate">
~$ pip install six==1.13.0
~$ pip install websocket-client==0.59.0
</pre>
<h2 id="wholton-using">上网认证使用</h2>
<p>上面依赖的库安装好之后，首先需要修改 <code>wholeton-auth.py</code> Python 程序中的配置（上面已经高亮显示了）：</p>
<pre class="brush: plain; title: ; notranslate">
wholeton_host = '192.168.1.254'
wholeton_user = 'test'
wholeton_pass = '123456'
wholeton_ip = ''
wholeton_mac = ''
update_secs = 28800
</pre>
<p>简单说明如下：</p>
<ul>
<li><code>wholeton_host</code> 指定惠尔顿上网行为管理系统 IP 地址；</li>
<li><code>wholeton_user</code> 和 <code>wholeton_pass</code> 指定上网行为管理的用户名和密码；</li>
<li><code>wholeton_ip</code> 为本机 IP 地址，默认为空，程序会自动获取，也可以自行修改覆盖；</li>
<li><code>wholeton_mac</code> 为本机上网网卡（也就是连接上网行为管理系统的网卡）的 MAC 地址，默认为空，程序也会自动获取（这里为了图省事使用的 <code>uuid</code> 库的 <code>getnode</code> 函数获取网卡 MAC 地址），也可以自行修改覆盖；</li>
<li><code>update_secs</code> 指定登录多长时间之后就强制断开连接进行重新登录，单位为秒，默认为 <code>28800</code> 秒也就是 8 个小时。</li>
</ul>
<p>因为我这边使用本程序测试发现惠尔顿的上网认证系统即使在保持 WebSocket 连接打开的情况下，大概 9 ~ 10 个小时之后也会无法上网，所以大家可以根据实际情况测试确认之后，修改程序里的 <code>update_secs</code> 重新登录时间。</p>
<p>修改完配置之后，使用起来就很简单了，根据 Python 版本在终端里运行 <code>python2 wholeton-auth.py</code> 或者 <code>python3 wholeton-auth.py</code> 就可以了，程序运行之后会在标准输出中显示上网认证服务器返回的响应数据。</p>
<p>最后本程序还是需要一直保持运行的，大家可以根据自己的需要通过 screen 或者服务等方式来实现后台运行哦。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/wholeton-linux-client/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ge.tt文件分享服务CLI及API的问题</title>
		<link>https://zohead.com/archives/ge-tt-cli-api/</link>
		<comments>https://zohead.com/archives/ge-tt-cli-api/#comments</comments>
		<pubDate>Mon, 17 Apr 2017 18:16:13 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[cURL]]></category>
		<category><![CDATA[ge.tt]]></category>
		<category><![CDATA[gett-cli]]></category>
		<category><![CDATA[分享]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1421</guid>
		<description><![CDATA[关于 ge.tt 最近我一直在寻找支持直链形式的文件分享服务： 支持通过 cURL 或者公开 API 上传文件生成分享地址； 用户可以通过 wget、cURL 等程序直接下载文件； 上传者后续可以更新文件并保持分享地址不变； 国内的普通用户可以正常访问下载分享的文件。 如果使用 Dropbox、Google Drive 应该也可以实现前面几个需求，但这两个网盘的最大问题在于国内难以描述的墙，而且上传下载还是稍微有点复杂。 以前我使用过 DriveHQ 服务，免费用户支持通过 FTP 方式上传文件（付费用户还支持通过 WebDAV 上传），上传到 Web 分享目录的文件可以直接通过 HTTP 下 [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 id="about-gett">关于 ge.tt</h2>
<p>最近我一直在寻找支持直链形式的文件分享服务：</p>
<ul>
<li>支持通过 cURL 或者公开 API 上传文件生成分享地址；</li>
<li>用户可以通过 wget、cURL 等程序直接下载文件；</li>
<li>上传者后续可以更新文件并保持分享地址不变；</li>
<li>国内的普通用户可以正常访问下载分享的文件。</li>
</ul>
<p>如果使用 Dropbox、Google Drive 应该也可以实现前面几个需求，但这两个网盘的最大问题在于国内难以描述的墙，而且上传下载还是稍微有点复杂。</p>
<p>以前我使用过 <a href="https://www.drivehq.com/" target="_blank">DriveHQ</a> 服务，免费用户支持通过 FTP 方式上传文件（付费用户还支持通过 WebDAV 上传），上传到 Web 分享目录的文件可以直接通过 HTTP 下载，这样也算能达到我的要求了，只是自动处理 FTP 上传覆盖要稍微麻烦点。</p>
<p>目前我使用的是 <a href="http://ge.tt/" target="_blank">ge.tt</a> 文件分享服务，相对 DriveHQ 来说其优势在于 ge.tt 开放了 API，而且也有第三方写的 Python / Perl / Java 等各种形式的文件管理工具。虽然 ge.tt 免费帐户只有 2GB 的存储空间，但仍然已经有 500 多万的用户分享了近 5000 万份文件，拿来分享一些小文件或者程序也是很方便的了。</p>
<p>ge.tt 提供了 REST 和 Live API，重点可以关注其 REST API（不过 ge.tt 官网的 API 说明文档暂时无法访问）：</p>
<p><a href="http://ge.tt/developers/overview" target="_blank">http://ge.tt/developers/overview</a></p>
<p>ge.tt 推荐在客户端上使用 gett-cli 工具来管理文件和分享，同样可以参考其官网说明：</p>
<p><a href="http://ge.tt/tools" target="_blank">http://ge.tt/tools</a></p>
<h2 id="gett-cli-problem">gett-cli 的问题</h2>
<p>gett-cli 工具基于 Python 3 实现，其 Bitbucket 项目主页为：</p>
<p><a href="https://bitbucket.org/mickael9/gett-cli/overview" target="_blank">https://bitbucket.org/mickael9/gett-cli/overview</a></p>
<p>查看项目说明显示该工具看起来也很简单，安装之后通过 <code>gett</code> 命令就可以管理了。<code>gett</code> 命令默认提供了上传文件、列表分享、删除分享、删除分享中的文件（一个分享地址支持包含多个文件）、搜索分享或文件的功能。</p>
<p>只是 gett-cli 在一开始登录的时候就碰到了问题，输入用户和密码之后直接登录失败：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ gett
Please enter your Ge.tt email: xxx@gmail.com
Please enter your Ge.tt password: 
Traceback (most recent call last):
  File &quot;/usr/local/bin/gett&quot;, line 11, in &lt;module&gt;
    load_entry_point('gett-cli==0.2.3', 'console_scripts', 'gett')()
  File &quot;/usr/local/lib/python3.4/dist-packages/gett_cli-0.2.3-py3.4.egg/gett/uploader.py&quot;, line 96, in entry_point
  File &quot;/usr/local/lib/python3.4/dist-packages/gett_cli-0.2.3-py3.4.egg/gett/uploader.py&quot;, line 198, in main
  File &quot;/usr/local/lib/python3.4/dist-packages/gett_cli-0.2.3-py3.4.egg/gett/gett.py&quot;, line 122, in login_auth
  File &quot;/usr/local/lib/python3.4/dist-packages/gett_cli-0.2.3-py3.4.egg/gett/gett.py&quot;, line 103, in _load
KeyError: 'accesstoken'
</pre>
<p>我在参考 ge.tt 的 REST API 说明之后使用 cURL 模拟登录请求，ge.tt 服务器也会返回 <code>Wrong credentials</code> 错误：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ curl -i -X POST --data '{&quot;email&quot;:&quot;xxx@gmail.com&quot;,&quot;password&quot;:&quot;test-pass&quot;}' http://
open.ge.tt/1/users/login
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Date: Wed, 05 Apr 2017 18:11:11 GMT
ETag: W/&quot;71-xxx+xxx&quot;
set-cookie: sails.sid=s%3Axxx-xxx%2FkOnG%2Bxxx%2Bxxx; Path=/; HttpOnly
Vary: X-HTTP-Method-Override, Accept-Encoding
X-Powered-By: Sails &lt;sailsjs.org&gt;
Content-Length: 113
Connection: keep-alive

{&quot;message&quot;:&quot;Wrong credentials&quot;,&quot;body&quot;:{&quot;err&quot;:&quot;Missing credentials&quot;},&quot;login&quot;:0,&quot;reason&quot;:{&quot;error&quot;:&quot;access denied&quot;}}
</pre>
<p>经过调试我才发现 ge.tt 的 REST API 请求中必须增加 <code>Content-Type: application/json;charset=UTF-8</code> 头才能正常返回数据。</p>
<p>修改 gett-cli 工具 Python 代码之后，现在 <code>gett</code> 命令可以正常返回用户使用的空间了：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ gett
Please enter your Ge.tt email: xxx@gmail.com
Please enter your Ge.tt password: 
Do you wish to store the session token? (y/n): y
Storage used: 232.81 KB out of 2.00 GB (0.0%)
</pre>
<p>登录成功之后 gett-cli 工具默认会将 Refresh Token 保存在用户主目录的 <code>.gett-token</code> 文件中：</p>
<pre class="brush: bash; title: ; notranslate">
root@ee9055d6b11f:~# cat .gett-token
r.0.user-25YKSbxxxxxxx-..xxxxxxx
</pre>
<p>这样后面再使用 gett-cli 工具就不用重复输入用户名和密码登录了。</p>
<h2 id="mod-gett-cli">修改 gett-cli</h2>
<p>另外我还发现 gett-cli 工具存在由于缺少文件大小参数导致上传的文件不正确等问题，为此我专门修改了 gett-cli 代码以解决登录和上传的问题。由于生成的 <code>gett-cli.patch</code> 补丁文件内容有点长这里就不贴出来了，有需要的话可以从下面的 Pastebin 地址下载：</p>
<p><a href="http://pastebin.com/raw/0siCtqkW" target="_blank">http://pastebin.com/raw/0siCtqkW</a></p>
<p>有动手能力的朋友们可以自行检出 Bitbucket 上的 gett-cli 版本库进行修改编译安装。</p>
<p>如果嫌编译麻烦也可以直接修改替换已经安装好的 gett-cli 工具 egg 文件，以我使用的 Ubuntu 系统上的 Python 3.4 为例，大概步骤如下（中间直接使用 <code>patch</code> 命令打补丁）：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ cp /usr/local/lib/python3.4/dist-packages/gett_cli-0.2.3-py3.4.egg .
(trusty)zzm@localhost:~/Downloads$ sudo unzip gett_cli-0.2.3-py3.4.egg &amp;&amp; rm -f gett_cli-0.2.3-py3.4.egg
Archive:  gett_cli-0.2.3-py3.4.egg
  inflating: EGG-INFO/zip-safe
  inflating: EGG-INFO/top_level.txt
  inflating: EGG-INFO/entry_points.txt
  inflating: EGG-INFO/dependency_links.txt
  inflating: EGG-INFO/SOURCES.txt
  inflating: EGG-INFO/PKG-INFO
  inflating: gett/uploader.py
  inflating: gett/gett.py
  inflating: gett/__init__.py
  inflating: gett/__pycache__/uploader.cpython-34.pyc
  inflating: gett/__pycache__/gett.cpython-34.pyc
  inflating: gett/__pycache__/__init__.cpython-34.pyc
(trusty)zzm@localhost:~/Downloads$ sudo patch -p2 &lt; gett-cli.patch
(trusty)zzm@localhost:~/Downloads$ sudo py3compile gett/gett.py gett/uploader.py
(trusty)zzm@localhost:~/Downloads$ sudo zip -r gett_cli-0.2.3-py3.4.egg EGG-INFO gett
  adding: EGG-INFO/ (stored 0%)
  adding: EGG-INFO/PKG-INFO (deflated 26%)
  adding: EGG-INFO/entry_points.txt (deflated 2%)
  adding: EGG-INFO/top_level.txt (stored 0%)
  adding: EGG-INFO/SOURCES.txt (deflated 48%)
  adding: EGG-INFO/dependency_links.txt (stored 0%)
  adding: EGG-INFO/zip-safe (stored 0%)
  adding: gett/ (stored 0%)
  adding: gett/uploader.py (deflated 68%)
  adding: gett/__pycache__/ (stored 0%)
  adding: gett/__pycache__/__init__.cpython-34.pyc (deflated 21%)
  adding: gett/__pycache__/gett.cpython-34.pyc (deflated 57%)
  adding: gett/__pycache__/uploader.cpython-34.pyc (deflated 48%)
  adding: gett/__init__.py (stored 0%)
  adding: gett/gett.py (deflated 71%)
(trusty)zzm@localhost:~/Downloads$ sudo mv gett_cli-0.2.3-py3.4.egg /usr/local/lib/python3.4/dist-packages/gett_cli-0.2.3-py3.4.egg
</pre>
<p>当然如果你不想在系统中安装 gett-cli 也可以直接下载使用我修改好的 gett 工具，解压缩之后运行其中的 <code>uploader.py</code> 程序即可（需要 Python 3 环境）：</p>
<p><a href="https://zohead.com/downloads/gett-cli-0.2.3.tar.gz">https://zohead.com/downloads/gett-cli-0.2.3.tar.gz</a></p>
<h2 id="use-gett-cli">使用 gett-cli 工具</h2>
<p>登录之后使用 gett-cli 工具上传文件非常简单，默认上传文件时都是创建新的分享，上传多个文件则直接附加多个文件参数：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ gett gett-cli-0.2.3.tar.gz
Creating file(s)...
--------------------------------------------------------------------------------
Share: Untitled (1 file(s)) [http://ge.tt/8D95lij2]
--------------------------------------------------------------------------------
 - gett-cli-0.2.3.tar.gz           6.54 KB  http://ge.tt/8D95lij2/v/0  remote

gett-cli-0.2.3.tar.gz  (  1/1) [########################################] 100 %

Storage used: 194.00  B out of 2.00 GB (0.0%)
</pre>
<p>上面结果中的 <code>http://ge.tt/8D95lij2</code> 就是新创建的文件分享地址，<code>http://ge.tt/8D95lij2/v/0</code> 则是该分享中某个文件的地址（<code>0</code> 是分享下的文件 ID，如果上传多个文件就会有 <code>v/1</code>、<code>v/2</code> 之类的文件地址）。</p>
<p>如果需要删除创建的分享可以运行：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ gett --delete http://ge.tt/8D95lij2
Deleted share: Untitled [http://ge.tt/8D95lij2]

Storage used: 6.74 KB out of 2.00 GB (0.0%)
</pre>
<p>用户如果需要下载分享中的文件那就更方便了，不需要 gett-cli 工具，直接一条 cURL 命令下载即可（替换命令中的分享地址和文件 ID）：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~/Downloads$ curl -k -o gett-cli-0.2.3.tar.gz -L -e &quot;http://ge.tt/8D95lij2&quot; &quot;http://api.ge.tt/1/files/8D95lij2/0/blob?download&quot;
</pre>
<h2 id="postscript">后记</h2>
<p>ge.tt 文件分享服务还存在一些小问题，比如某个分享中已经上传的文件目前还无法直接以相同的文件 ID 进行覆盖替换（例如上面例子中的 <code>http://ge.tt/8D95lij2/v/0</code>），只能删除文件再上传新文件到该分享，新上传的文件的 ID 只能递增，不能保持原来的文件 ID（例如删除之后新上传的文件 ID 可能是 <code>http://ge.tt/8D95lij2/v/3</code>）。</p>
<p>结合这段时间我的使用感觉来看，ge.tt 用于分享小文件还算比较方便的，很适合一些需要通过工具或命令自动上传下载文件的场合。最后如果文章中有任何问题，还请提出指正，祝大家玩的开心。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/ge-tt-cli-api/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>PPTV XBMC视频插件更新-v1.2.9</title>
		<link>https://zohead.com/archives/pptv-xbmc-v1-2-9/</link>
		<comments>https://zohead.com/archives/pptv-xbmc-v1-2-9/#comments</comments>
		<pubDate>Wed, 20 Jan 2016 15:47:21 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[XBMC]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[FLVCD]]></category>
		<category><![CDATA[m3u8]]></category>
		<category><![CDATA[PPTV]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1146</guid>
		<description><![CDATA[先预告下这有可能是我对 PPTV XBMC 视频插件做的最后一次修改更新了，之前最近一次的更新还是 2014 年 12 月份修改的，中间这一年时间我已经很少使用 XBMC 媒体中心播放视频了，因为之前用的是一代树莓派搭的 XBMC 媒体中心，在 2015 年买了 Android 迷你 TV 棒之后由于可以直接安装各种 TV 版和 HD 版的 Android 视频 App 使用起来明显方便了很多，这样就差不多让树莓派在那吃灰了 -_-#。 前几天收到某网友发的邮件说 PPTV 插件不能用了，我花了一天时间调试修改了原来的 1.2.8 版本 PPTV XBMC 插件（顺便复习下 Python ^_ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>先预告下这有可能是我对 PPTV XBMC 视频插件做的最后一次修改更新了，之前最近一次的更新还是 2014 年 12 月份修改的，中间这一年时间我已经很少使用 XBMC 媒体中心播放视频了，因为之前用的是一代树莓派搭的 XBMC 媒体中心，在 2015 年买了 Android 迷你 TV 棒之后由于可以直接安装各种 TV 版和 HD 版的 Android 视频 App 使用起来明显方便了很多，这样就差不多让树莓派在那吃灰了 -_-#。</p>
<p>前几天收到某网友发的邮件说 PPTV 插件不能用了，我花了一天时间调试修改了原来的 1.2.8 版本 PPTV XBMC 插件（顺便复习下 Python ^_^），并在昨天更新到了 1.2.9 版本，主要改动如下：</p>
<ul>
<li>解决 PPTV 网站改版后搜索功能不能返回结果的问题；</li>
<li>解决得到全国电视台列表时可能出错导致 XBMC 提示脚本错误问题；</li>
<li>解决无法得到 Flash 方式分段 mp4 视频地址的问题；</li>
<li>由于 PPTV 将 m3u8 回放视频限制为 10 分钟（PPTV 的 iPad、Android 等手机网页版播放视频同样有 10 分钟的限制），默认禁用 iPad 流媒体视频播放模式。</li>
</ul>
<p>我的 PPTV XBMC 视频插件项目地址：</p>
<p><a href="https://github.com/zohead/pptv4xbmc">https://github.com/zohead/pptv4xbmc</a></p>
<p>PPTV 插件现在也已经直接合并到 <a href="https://github.com/taxigps/xbmc-addons-chinese">XBMC Chinese Add-ons</a> 仓库中的，如果你的 XBMC 中已经安装了 XBMC Chinese Add-ons 插件仓库那应该是能自动收到此视频插件更新的哦。</p>
<p>1.2.8 版本不能得到 Flash 方式分段 mp4 视频地址的原因是 <a href="http://www.flvcd.com/">FLVCD</a> 网站的客户端获取视频播放 key 的方式做了修改，加了一个比较简单的凯撒加密验证，做了对应的修改之后就可以正确获取播放的 key 了。</p>
<blockquote>
<p><strong>提示</strong></p>
<p>查看 FLVCD 的网页源代码还可以看到其凯撒加密的代码看起来是有一处明显的错误哦，不过为了插件能正常工作只能按照 FLVCD 的处理方式来修改了。</p>
</blockquote>
<p>我在此插件的修改更新过程中还是明显感觉到在 PPTV 官方没有开放 API 的情况下写 XBMC 插件是一件比较麻烦和没意思的事情，PPTV 网站或者未公开的接口做了修改之后插件就很可能不能用了，另外 PPTV 现在也比较恶心的和土豆网学习开始限制手机、平板等移动设备网页版在线视频的长度，而且国内的视频网站大抵都是如此做了各种限制，没有 YouTube 那样相对比较开放的心态。</p>
<p>现有中文插件库里面的插件普遍由于上面列出的类似种种原因工作方式都比较低效，如果像 FLVCD 那样用反编译等方式实现自动解析地址也需要随时跟着视频网站的修改做对应更新（而且 FLVCD 还只实现了视频地址解析，视频列表、搜索、分类之类的都是没有的）感觉也是挺麻烦的，这样国内的 XBMC 用户最直接的感觉就是这些视频插件经常不能正常工作。</p>
<p>因此考虑在现有 Android 等电视盒子的生态环境已经非常完善，同时各种影视聚合软件的使用体验已经完全超过 XBMC 目前的视频插件的情况下，我基本不会再对 PPTV XBMC 插件做太多修改了，后面如果 PPTV 网站或者接口有大的修改导致插件不能使用的话也不太会去更新了，估计只有碰到一些小的变动时才会做对应修改。</p>
<p>如果有其他开发者愿意加入或接手这个 XBMC 插件的开发也是非常欢迎的哦，最后还是祝大家玩的开心。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/pptv-xbmc-v1-2-9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PPTV XBMC视频插件更新-v1.2.0</title>
		<link>https://zohead.com/archives/pptv-xbmc-plugin-v1-2-0/</link>
		<comments>https://zohead.com/archives/pptv-xbmc-plugin-v1-2-0/#comments</comments>
		<pubDate>Sun, 03 Nov 2013 16:35:54 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[XBMC]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[PPTV]]></category>
		<category><![CDATA[xbmc-addons-chinese]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[点播]]></category>
		<category><![CDATA[视频]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=606</guid>
		<description><![CDATA[本文同步自（最佳显示效果请点击）：https://zohead.com/archives/pptv-xbmc-plugin-v1-2-0/ 6月份更新 PPTV 的 XBMC 视频插件到 1.1.9 版本之后一直没有再更新，最近发现 PPTV 网站已经有了非常大的修改，造成 PPTV 的 XBMC 视频插件无法正常工作，包括获取视频类别列表、视频列表、视频播放在内的众多功能都运行错误。因此，这两天花了点时间更新了 PPTV 插件，现仍然支持 PPTV 上的点播和直播视频。 1.2.0 版本主要更新内容如下： 针对 PPTV 网站的主要改动解决插件无法正常工作的问题； 解决无法获取视频类别列表的 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文同步自（最佳显示效果请点击）：<a href="https://zohead.com/archives/pptv-xbmc-plugin-v1-2-0/" target="_blank">https://zohead.com/archives/pptv-xbmc-plugin-v1-2-0/</a></p>
<p>6月份更新 PPTV 的 XBMC 视频插件到 1.1.9 版本之后一直没有再更新，最近发现 PPTV 网站已经有了非常大的修改，造成 PPTV 的 XBMC 视频插件无法正常工作，包括获取视频类别列表、视频列表、视频播放在内的众多功能都运行错误。因此，这两天花了点时间更新了 PPTV 插件，现仍然支持 PPTV 上的点播和直播视频。</p>
<p>1.2.0 版本主要更新内容如下：</p>
<ul>
<li>针对 PPTV 网站的主要改动解决插件无法正常工作的问题；</li>
<li>解决无法获取视频类别列表的问题；</li>
<li>解决无法获取视频列表的问题；</li>
<li>解决无法获取连续剧等剧集列表的问题；</li>
<li>解决无法正确获取 Flash 和 iPad m3u8 视频地址的问题；</li>
<li>视频类别列表中增加所有直播节目列表；</li>
<li>按照不同区域列表获取所有直播电视台节目列表；</li>
<li>使用 PPTV 新 API 获取体育直播、游戏直播、财经直播节目单；</li>
<li>正确获取体育直播、游戏直播、财经直播等特殊节目的视频地址。</li>
</ul>
<p>由于 PPTV 的直播电视台是按区域划分的，因此获取列表时需要重复多次请求，可能等待时间会稍微有点长，由于暂时没有直接获取整个列表的方法，就只能先这么办了。此插件使用时如果有任何问题，请提出指正。</p>
<p>与之前的版本类似，PPTV XBMC 视频插件默认使用 m3u8 格式播放直播和点播视频，这样视频显示出来只有一个小节，没有切换时的缓冲问题；如果您使用的 XBMC 系统播放 m3u8 视频存在问题请在选项中关闭 “使用iPad m3u8流媒体视频” 选项。</p>
<p>安装 PPTV XBMC 视频插件之前需先安装 xbmc-addons-chinese 中文扩展库支持：</p>
<p><a href="http://code.google.com/p/xbmc-addons-chinese/downloads/list" target="_blank">http://code.google.com/p/xbmc-addons-chinese/downloads/list</a></p>
<p>通过 XBMC 中文插件库安装的朋友可以直接在线更新升级到 1.2.0 版本，也可以通过下载下面的安装包进行安装：</p>
<p><a href="http://miseal.googlecode.com/files/plugin.video.pptv-v1.2.0.zip" target="_blank">http://miseal.googlecode.com/files/plugin.video.pptv-v1.2.0.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/pptv-xbmc-plugin-v1-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PPTV XBMC视频插件更新-v1.1.8</title>
		<link>https://zohead.com/archives/pptv-xbmc-plugin-v1-1-8/</link>
		<comments>https://zohead.com/archives/pptv-xbmc-plugin-v1-1-8/#comments</comments>
		<pubDate>Thu, 09 May 2013 12:56:08 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[XBMC]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[m3u8]]></category>
		<category><![CDATA[PPTV]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[视频]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=422</guid>
		<description><![CDATA[本文同步自（最佳显示效果请点击）：https://zohead.com/archives/pptv-xbmc-plugin-v1-1-8/ 去年写了一个 XBMC 媒体中心系统上的 PPTV 视频插件（参考 [这里]），自从去年快 11 月份更新之后就再没有管过。今天无意到 htpc XBMC 论坛（参考 [这里]）逛了下，发现有不少网友跟帖反映插件已经无法正常播放视频，故考虑可能的话更新下 PPTV 视频插件。 比较意外的是我发现 XBMC 中文插件库中我所提交的 PPTV 视频插件的最后版本号为 1.1.3 版本，但有网友 cmeng 已经做了一些改动，将插件的版本更新为了 1.1.7 版 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文同步自（最佳显示效果请点击）：<a href="https://zohead.com/archives/pptv-xbmc-plugin-v1-1-8/" target="_blank">https://zohead.com/archives/pptv-xbmc-plugin-v1-1-8/</a></p>
<p>去年写了一个 XBMC 媒体中心系统上的 PPTV 视频插件（参考 [<a href="https://zohead.com/archives/pptv-xbmc-plugin/" target="_blank">这里</a>]），自从去年快 11 月份更新之后就再没有管过。今天无意到 htpc XBMC 论坛（参考 [<a href="http://bbs.htpc1.com/thread-259452-1-1.html" target="_blank">这里</a>]）逛了下，发现有不少网友跟帖反映插件已经无法正常播放视频，故考虑可能的话更新下 PPTV 视频插件。</p>
<p>比较意外的是我发现 XBMC 中文插件库中我所提交的 PPTV 视频插件的最后版本号为 1.1.3 版本，但有网友 cmeng 已经做了一些改动，将插件的版本更新为了 1.1.7 版本，而且增加了 Windows 上才有的 PPAP 加速进程选项（更新的插件描述中也有错误，写成了 PPSAP）。由于我写这个免费 XBMC 视频插件是目的就是为了实现平台无关的 PPTV 视频播放，因此打算在新版本中去掉 PPAP 的选项，并且统一解决目前 1.1.3 版本中的问题。</p>
<p>由于 PPTV 网站内容更改，原先通过硕鼠得到视频地址的方法无法起作用，由于 PPTV 官方没有提供可用的 API 给我们调用，而且硕鼠现在提交 PPTV 视频播放页面地址后无法直接得到视频地址，必须通过硕鼠的客户端下载视频。在此情况下，经过研究硕鼠的获取视频和下载流程，终于通过多步的请求操作得到真实 PPTV 视频地址的方法。有兴趣的网友请参考代码库中的得到视频地址的 Python 代码。</p>
<p>由于 1.1.4 ~ 1.1.7 版本并不是我自己更新（网友 cmeng 所更新），因此新的版本考虑已经安装的网友自动更新的需要，只能将版本号直接改成 1.1.8 了。另外 PPTV 视频插件仍然会尽量保证平台无关性，以使本插件可在绝大多数 XBMC 系统中运行。</p>
<p>1.1.8 版本的主要更新记录为：</p>
<ul>
<li>移除 cmeng 提交的 1.1.4 ~ 1.1.7 版本中的平台相关的 PPSAP 加速选项；</li>
<li>解决搜索视频无法正常工作的问题；</li>
<li>解决搜索视频没有包含完整搜索结果的问题；</li>
<li>解决无法得到 PPTV 视频地址的问题；</li>
<li>解决无法得到 iPad m3u8 流媒体视频地址的问题；</li>
<li>为 iPad m3u8 流媒体视频单独增加设置开关，这样 iPad 视频也可以选择清晰度；</li>
<li>iPad m3u8 流媒体视频需要 XBMC 播放器能支持 m3u8 播放，选项默认开启，如果无法正常播放，可以在设置界面中关闭 iPad m3u8 流媒体视频选项；</li>
<li>在插件信息中增加源代码地址、论坛帖子地址、本人邮箱、本人博客等信息，方便出现问题时联系。</li>
</ul>
<p>有关单独增加的 iPad m3u8 流媒体视频选项，可以看下面的截图：</p>
<p><a href="http://zohead.com/wp-content/uploads/pptv-xbmc-m3u8-option.jpg"><img class="alignnone" title="PPTV XBMC插件 - iPad m3u8 视频选项" src="http://zohead.com/wp-content/uploads/pptv-xbmc-m3u8-option.jpg" alt="PPTV XBMC插件 - iPad m3u8 视频选项" width="640" height="360" /></a></p>
<p>不同于之前的版本，1.1.8 中可以单独设置是否使用 iPad m3u8 流媒体视频，默认为开启。如果 XBMC 播放器能够正常播放的话，也建议默认开启。</p>
<p>下面就是开启 iPad m3u8 流媒体视频的好处：</p>
<p><a href="http://zohead.com/wp-content/uploads/pptv-xbmc-m3u8-video.jpg"><img class="alignnone" title="PPTV XBMC插件 - iPad m3u8 视频" src="http://zohead.com/wp-content/uploads/pptv-xbmc-m3u8-video.jpg" alt="PPTV XBMC插件 - iPad m3u8 视频" width="640" height="360" /></a></p>
<p>从上面视频播放画面的截图可以看出，iPad m3u8 流媒体视频就是一个完整的视频（从上图中可以看出视频只有 1 节，而且右下角显示的时长为 1 个小时 41 分钟），这样播放时就不会出现切换视频时的缓冲情况，相当于真正的无缝播放整个影片。</p>
<p>而如果没有开启 iPad m3u8 流媒体视频，则整个影片很可能会按 3 - 10 分钟不等的小片段进行划分，这样播放时就需要隔几分钟缓存一次，有点影响观看体验。据我了解，目前 XBMC 中文插件库中的优酷等视频插件都存在这个问题，因此如果你的 XBMC 播放器能正常播放 iPad m3u8 流媒体视频的话，强烈建议不要关闭它。</p>
<p>最后是 1.1.8 版本 PPTV XBMC 视频插件的下载地址：</p>
<p><a href="http://miseal.googlecode.com/files/plugin.video.pptv-v1.1.8.zip" target="_blank">http://miseal.googlecode.com/files/plugin.video.pptv-v1.1.8.zip</a></p>
<p>如果您已经通过 XBMC 中文插件库安装了 PPTV 视频插件，可以直接通过 XBMC 系统进行在线更新。</p>
<p>对源代码有兴趣进行修改的网友请移步 GitHub 上的版本库：</p>
<p><a href="https://github.com/zohead/pptv4xbmc" target="_blank">https://github.com/zohead/pptv4xbmc</a></p>
<p>插件使用中有任何问题和建议，欢迎与我联系，玩的开心 ^_^</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/pptv-xbmc-plugin-v1-1-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PPTV XBMC视频插件更新-v1.1.2</title>
		<link>https://zohead.com/archives/pptv-xbmc-plugin-v1-1-2/</link>
		<comments>https://zohead.com/archives/pptv-xbmc-plugin-v1-1-2/#comments</comments>
		<pubDate>Tue, 30 Oct 2012 13:43:21 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[XBMC]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[m3u8]]></category>
		<category><![CDATA[PPTV]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[视频]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=332</guid>
		<description><![CDATA[本文同步自（最佳显示效果请点击）：https://zohead.com/archives/pptv-xbmc-plugin-v1-1-2/ 之前利用闲余时间写了个 PPTV 的 XBMC 多媒体中心系统的视频插件 v1.0 版本（请参考 [这里]），在 htpc XBMC 论坛上公布之外，经过几百个论坛网友下载使用之后，也发现一些问题，经过修正和增强之后更新了 1.1.2 版本的新 PPTV 视频插件。 更新内容如下： 由于 Python 2.5 以下版本不支持三目运算符，为兼容 Xbox XBMC 等老的 Python 环境，将 if else 三目运算符改换为普通的方式； 解决 PPTV  [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文同步自（最佳显示效果请点击）：<a href="https://zohead.com/archives/pptv-xbmc-plugin-v1-1-2/" target="_blank">https://zohead.com/archives/pptv-xbmc-plugin-v1-1-2/</a></p>
<p>之前利用闲余时间写了个 PPTV 的 XBMC 多媒体中心系统的视频插件 v1.0 版本（请参考 [<a href="https://zohead.com/archives/pptv-xbmc-plugin/" target="_blank">这里</a>]），在 htpc XBMC 论坛上公布之外，经过几百个论坛网友下载使用之后，也发现一些问题，经过修正和增强之后更新了 1.1.2 版本的新 PPTV 视频插件。</p>
<p>更新内容如下：</p>
<ul>
<li>由于 Python 2.5 以下版本不支持三目运算符，为兼容 Xbox XBMC 等老的 Python 环境，将 if else 三目运算符改换为普通的方式；</li>
<li>解决 PPTV 直播电视节目单获取错误的问题；</li>
<li>如果某个 PPTV 直播节目没有节目单，不能直接得到播放页面地址，则尝试通过搜索的方式得到播放页面地址；</li>
<li>引入 XBMC Chinese Keyboard 插件，为本插件增加根据关键字搜索 PPTV 视频的功能；</li>
<li>如果搜索到的视频不是由 PPTV 提供（例如：优酷、土豆之类），则在播放时给出提示；</li>
<li>播放 PPTV VIP 视频时提示用户无法播放 VIP 视频；</li>
<li>解决某些连续剧集节目（例如某些动漫剧场版全集）无法得到视频列表的问题。</li>
</ul>
<p>针对某些网友提出的选择播放到开始缓冲间有点延时的问题，由于需要从 PPTV 未公开的 API 中获取真实视频地址，暂时没有什么好的办法解决。另外 PPTV 直播视频仍然使用的是 m3u8 格式的 HTTP live stream，需要 XBMC 系统能正常播放这种流媒体视频。</p>
<p>最后放出 1.1.2 版本 PPTV XBMC 视频插件下载地址：</p>
<p><a href="http://github.com/downloads/zohead/pptv4xbmc/plugin.video.pptv-v1.1.2.zip" target="_blank">http://github.com/downloads/zohead/pptv4xbmc/plugin.video.pptv-v1.1.2.zip</a></p>
<p>使用此插件过程中有任何问题欢迎指正哦 ^_^</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/pptv-xbmc-plugin-v1-1-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>发布PPTV XBMC视频插件v1.0</title>
		<link>https://zohead.com/archives/pptv-xbmc-plugin/</link>
		<comments>https://zohead.com/archives/pptv-xbmc-plugin/#comments</comments>
		<pubDate>Tue, 23 Oct 2012 15:05:36 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[XBMC]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[树莓派]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Beautiful Soup]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[m3u]]></category>
		<category><![CDATA[m3u8]]></category>
		<category><![CDATA[Parsedom]]></category>
		<category><![CDATA[PPTV]]></category>
		<category><![CDATA[扩展]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[视频]]></category>
		<category><![CDATA[跨平台]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=325</guid>
		<description><![CDATA[本文同步自（最佳显示效果请点击）：https://zohead.com/archives/pptv-xbmc-plugin/ 最近认识一位朋友想要在 XBMC 多媒体中心软件（http://www.xbmc.org/）上观看 PPTV（http://www.pptv.com/） 视频网站上的视频，看到有 Windows 上的 XBMC PPTV 插件，但都没法在我的 Raspberry Pi 微型电脑板上（板子虽小也支持播放 1080p 高清视频哦）运行，于是想着自己写个能够跨平台的 PPTV 视频的 XBMC 插件，顺便也拿这个练练 Python，HOHO。 既然要跨平台，那首先考虑必须全部 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文同步自（最佳显示效果请点击）：<a href="https://zohead.com/archives/pptv-xbmc-plugin/" target="_blank">https://zohead.com/archives/pptv-xbmc-plugin/</a></p>
<p>最近认识一位朋友想要在 XBMC 多媒体中心软件（<a href="http://www.xbmc.org/" target="_blank">http://www.xbmc.org/</a>）上观看 PPTV（<a href="http://www.pptv.com/" target="_blank">http://www.pptv.com/</a>） 视频网站上的视频，看到有 Windows 上的 XBMC PPTV 插件，但都没法在我的 Raspberry Pi 微型电脑板上（板子虽小也支持播放 1080p 高清视频哦）运行，于是想着自己写个能够跨平台的 PPTV 视频的 XBMC 插件，顺便也拿这个练练 Python，HOHO。</p>
<p>既然要跨平台，那首先考虑必须全部用 XBMC 自带的 Python 脚本实现，不能调用 Windows 上 DLL 之类的鬼玩意，而且 Raspberry Pi 的 armhf 系统上也几乎不可能有 PPTV 的动态库可以用的。</p>
<p><strong>基本原理：</strong></p>
<p>通过 Python 插件发送 HTTP 请求时伪装成 iPad 客户端从 PPTV 网站上获取频道列表、视频列表、查询视频，并得到视频的实际 m3u 和 m3u8 地址。后来发现此方法得到的 m3u 和 m3u8 视频地址在 Raspberry Pi 系统中播放有问题，而且不太好直接解决。没办法，咱拿起 Wireshark 抓包神器，终于发现了 PPTV 未公开的 API 方法（其实 PPTV 一直从未公开，哈哈）得到网页 Flash 方式播放的视频地址。不过其中有个视频 key 的问题，没什么太好办法在 Python 中直接得到。最终想到通过 [<a href="http://www.flvcd.com/" target="_blank">硕鼠</a>] 网站解决，硕鼠网站得到的 PPTV 视频地址明显有问题，但有个可用之处就是他能通过 Flash 得到 PPTV 的视频 key，那就省点事从硕鼠得到视频 key，从 PPTV 未公开 API 构造视频链接和分段信息（用过 Python 自带的 json 库），最终得到真实的视频地址。</p>
<p>有关 XBMC 的插件编写详细请参考这些链接：</p>
<p><a href="http://wiki.xbmc.org/index.php?title=HOW-TO:Write_plugins_for_XBMC" target="_blank">http://wiki.xbmc.org/index.php?title=HOW-TO:Write_plugins_for_XBMC</a><br />
<a href="http://wiki.xbmc.org/index.php?title=Python_development" target="_blank">http://wiki.xbmc.org/index.php?title=Python_development</a><br />
<a href="http://wiki.xbmc.org/index.php?title=Add-on_development" target="_blank">http://wiki.xbmc.org/index.php?title=Add-on_development</a></p>
<p>其中遇到的一个问题就是 HTML 的解析问题，刚开始使用的是比较成熟好用的一个 Python 插件：<a href="http://www.crummy.com/software/BeautifulSoup/" target="_blank">Beautiful Soup</a>。这个插件的最大优势就是对不标准的 HTML 的容错性做的非常好，而且各种查找 HTML DOM 结构的函数也很强大。那就按照 Beautiful Soup 的要求解析 PPTV 的 HTML DOM，结果顺利取得，不久就发现一个问题，在 Raspberry Pi 这种比较弱的嵌入式板子上，下载 HTML 倒挺快，通过 Beautiful Soup 解析查找 HTML DOM 竟然要用去 15 秒左右的时间，这完全无法忍受，可以寻找替代品。</p>
<p>最终在 XBMC 的论坛里发现了比较好的 HTML parser 替代品：<a href="http://wiki.xbmc.org/index.php?title=Add-on:Parsedom_for_xbmc_plugins" target="_blank">Parsedom XBMC Add-on</a>。这是直接包含在 XBMC 库中的一个简单的 HTML DOM 解析扩展，import 之，下载 HTML 然后按照 class、按照 id 解析 HTML 的速度都在 1-2 秒之间，非常满意。后来使用中又发现 Parsedom 中存在的一些问题，查找原因并修正之后无伤大雅，想到干脆去掉 Parsedom 中一些我用不到的代码，直接集成到我的 py 文件中使用 ^_^。</p>
<p>略加奋战，终于在 XBMC 界面上能正常显示了，能显示频道列表了，也能进入频道显示视频列表，结果播放时发现悲剧了，iPad 的 m3u 被 XBMC 自己给分段解析然后尝试播放了，造成文件路径不对无法播放。后来使用手工修改路径的方式，尽管能播放，但造成的“效果”就是每 5-6 秒钟就需要切换一下视频，这对于 Raspberry Pi 这种暂时无法调用外部播放器的系统来说简直没法用。</p>
<p><strong>PPTV 视频 XBMC 插件 1.0 版本功能：</strong></p>
<ol>
<li>支持 www.pptv.com 上基本所有直播和点播视频；</li>
<li>支持在插件设置中选择视频质量（与实际 PPTV 视频片源对应），暂时支持：标清、高清、超清、蓝光、iPad 超清；</li>
<li>支持按影片类型、时间、更新时间、热度等条件选择过滤视频，并且所有过滤条件全部实时从 PPTV 网站获取，插件中不保存分类；</li>
<li>视频列表支持翻页处理（具体每个连续剧的集数列表没有翻页，默认全部列出来，主要感觉 1-40 集这种列表还弄分页没什么必要）；</li>
<li>不依赖任何 PPTV 的 Windows 程序和库，理论上可以在任何 XBMC 系统上使用</li>
</ol>
<p>由于 XBMC 不能原生支持中文输入等原因，暂时未支持视频搜索功能，后续将会改进。</p>
<p><strong>备注：</strong></p>
<p>本插件默认的视频质量为高清格式，需要超清或蓝光格式的在插件设置界面中进行修改即可。iPad 超清视频和直播视频分别是特殊的 m3u 和 m3u8 格式（指向 mp4 视频），需要XBMC 系统能正常播放 PPTV m3u 和 m3u8 视频（Windows 下的 XBMC 系统应该可以配置使用外部播放器来支持，不过偶懒得安装木有测试过）。</p>
<p><strong>声明：</strong></p>
<p>此插件只是从 PPTV 网站获取视频内容，所有视频版权均与此网站有关，本插件一概不负责。另外由于 PPTV 网站将来会有变化，我不保证能马上修复并解决可能出现的问题，因为说不定 PPTV 就完全把未公开的 API 给禁用了。</p>
<p>插件介绍的截图：</p>
<p><a href="http://zohead.com/wp-content/uploads/pptv-xbmc-intro.jpg" target="_blank"><img class="alignnone" title="PPTV视频XBMC插件-介绍" src="http://zohead.com/wp-content/uploads/pptv-xbmc-intro.jpg" alt="PPTV视频XBMC插件-介绍" width="683" height="384" /></a></p>
<p>插件设置界面：</p>
<p><a href="http://zohead.com/wp-content/uploads/pptv-xbmc-settings.jpg" target="_blank"><img class="alignnone" title="PPTV视频XBMC插件-设置" src="http://zohead.com/wp-content/uploads/pptv-xbmc-settings.jpg" alt="PPTV视频XBMC插件-设置" width="683" height="384" /></a></p>
<p>视频列表界面：</p>
<p><a href="http://zohead.com/wp-content/uploads/pptv-xbmc-video-list.jpg" target="_blank"><img class="alignnone" title="PPTV视频XBMC插件-视频列表" src="http://zohead.com/wp-content/uploads/pptv-xbmc-video-list.jpg" alt="PPTV视频XBMC插件-视频列表" width="683" height="384" /></a></p>
<p>具体视频播放界面（放的正是 《麦兜》 哈 ^_^）：</p>
<p><a href="http://zohead.com/wp-content/uploads/pptv-xbmc-video-play.jpg" target="_blank"><img class="alignnone" title="PPTV视频XBMC插件-播放界面" src="http://zohead.com/wp-content/uploads/pptv-xbmc-video-play.jpg" alt="PPTV视频XBMC插件-播放界面" width="683" height="384" /></a></p>
<p>本 XBMC 插件的 github 源代码库地址：</p>
<p><a href="https://github.com/zohead/pptv4xbmc" target="_blank">https://github.com/zohead/pptv4xbmc</a></p>
<p>下载 PPTV 视频 XBMC 插件：</p>
<p><a href="http://github.com/downloads/zohead/pptv4xbmc/plugin.video.pptv-v1.0.zip" target="_blank">http://github.com/downloads/zohead/pptv4xbmc/plugin.video.pptv-v1.0.zip</a></p>
<p>下载之后拷贝到 XBMC 系统，然后到 XBMC 系统设置中选择压缩包安装即可。我正在申请将此款插件加入 XBMC 的中文插件库，顺利的话安装此插件将会更加简单，并且在以后修改时可以直接在线更新。</p>
<p>各位在使用 PPTV 视频 XBMC 插件中如果发现任何问题，欢迎提出指正哦，另外有问题时最好能描述清楚，能附上看的是哪个视频或者哪个频道下面的话更好。 ^_^</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/pptv-xbmc-plugin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>修改XBMC LiveStreams Python插件以支持中文</title>
		<link>https://zohead.com/archives/xbmc-livestreams-cn-patch/</link>
		<comments>https://zohead.com/archives/xbmc-livestreams-cn-patch/#comments</comments>
		<pubDate>Mon, 03 Sep 2012 18:49:07 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[树莓派]]></category>
		<category><![CDATA[HTPC]]></category>
		<category><![CDATA[LiveStreams]]></category>
		<category><![CDATA[Openelec]]></category>
		<category><![CDATA[Raspbmc]]></category>
		<category><![CDATA[XBian]]></category>
		<category><![CDATA[XBMC]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[插件]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=299</guid>
		<description><![CDATA[本文同步自（最佳显示效果请点击）：https://zohead.com/archives/xbmc-livestreams-cn-patch/ 最近在闲时捣鼓下 Raspberry Pi 微型电脑板上的开源 XBMC 应用准备看看 HTPC 媒体中心的效果，发现 Raspberry Pi 在安装了 XBian 系统之后可以比较好的实现 XBMC 的基本功能，虽然由于 Raspberry Pi 没有购买一些视频格式的软件解码授权而导致 WMV 或者 MMS 之类的格式无法播放，但对于常用的一些 H264 的高清视频已经足以应付，接上网线之后看高清在线视频点播和直播的效果都还可以。 有关 Rasp [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文同步自（最佳显示效果请点击）：<a href="https://zohead.com/archives/xbmc-livestreams-cn-patch/" target="_blank">https://zohead.com/archives/xbmc-livestreams-cn-patch/</a></p>
<p>最近在闲时捣鼓下 Raspberry Pi 微型电脑板上的开源 XBMC 应用准备看看 HTPC 媒体中心的效果，发现 Raspberry Pi 在安装了 XBian 系统之后可以比较好的实现 XBMC 的基本功能，虽然由于 Raspberry Pi 没有购买一些视频格式的软件解码授权而导致 WMV 或者 MMS 之类的格式无法播放，但对于常用的一些 H264 的高清视频已经足以应付，接上网线之后看高清在线视频点播和直播的效果都还可以。</p>
<p>有关 Raspberry Pi 请参考 [<a href="https://zohead.com/archives/raspberry-pi-start/" target="_blank">之前</a>] 的文章，有关 XBian 之一专门为 Raspberry Pi 优化的 XBMC 系统可以访问其官网：<a href="http://xbian.org/" target="_blank">http://xbian.org/</a>。</p>
<p>注：Raspberry Pi 上除了 XBian 之外，还有 <a href="http://www.raspbmc.com/" target="_blank">Raspbmc</a>、<a href="http://openelec.tv/" target="_blank">Openelec</a> 等其它合适的 XBMC 系统可供选择的。而且这些都是基于标准 XBMC 程序修改的，标准插件之类的基本可以通用。</p>
<p>前两天找到一个不错的在线电视直播的 XBMC 插件：LiveStreams，此插件可以由用户自己修改 XML 配置文件增加在线直播的地址，根据实际硬件配置不同，可支持 MMS、RTSP、RTMP 等各种不同的流媒体协议。有关 LiveStreams 的介绍和配置请参考这些链接（特别第二个链接中有详细的截图介绍）：</p>
<p><a href="http://forum.xbmc.org/showthread.php?tid=97116" target="_blank">http://forum.xbmc.org/showthread.php?tid=97116</a><br />
<a href="http://www.xbmchub.com/blog/2012/04/26/adding-custom-xml-files-to-the-live-streams-addon/" target="_blank">http://www.xbmchub.com/blog/2012/04/26/adding-custom-xml-files-to-the-live-streams-addon/</a></p>
<p>最新版本的 LiveStreams 插件可以到这里下载：<a href="http://code.google.com/p/divingmules-repo/" target="_blank">http://code.google.com/p/divingmules-repo/</a>。</p>
<p>在实际使用过程中发现由于 LiveStreams 由于是老外写的，不由自主的就碰到对中文的支持问题，如果添加的 XML 配置文件中节目名称或者节目目录名称包含中文，XBMC 系统中LiveStreams 插件将不能正常工作，直接会出现脚本错误。</p>
<p>简单看了下 LiveStreams 插件的代码，是用 Python 写的，凭着一些简单的 Python 基础，然后集合 Python 的 logging 模块来调试，终于发现 LiveStreams 插件对中文支持不佳的原因，作者在使用 BeautifulSoup（参考 [<a href="http://www.crummy.com/software/BeautifulSoup/" target="_blank">这里</a>]） 这一个非常知名的 HTML/XML 等解析的库时未考虑非英文环境下的问题，简单做了下修改之后，中文的直播节目和目录名称都可以正常显示了。</p>
<p>顺便再简单说明一下 LiveStreams XML 配置文件嵌套节目目录的方式，这是一个实例 XML 节目配置文件：</p>
<pre class="brush: xml; title: channels.xml; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;channels&gt;
	&lt;channel&gt;
		&lt;name&gt;Channel 1&lt;/name&gt;
		&lt;thumbnail&gt;http://xxx/chn1.png&lt;/thumbnail&gt;
		&lt;items&gt;
			&lt;item&gt;
				&lt;title&gt;TV1&lt;/title&gt;
				&lt;link&gt;mms://xxx.xxx.xxx.xxx/cctv1&lt;/link&gt;
				&lt;thumbnail&gt;http://xxx/cctv1.jpg&lt;/thumbnail&gt;
			&lt;/item&gt;
			&lt;item&gt;
				&lt;title&gt;TV2&lt;/title&gt;
				&lt;link&gt;mms://xxx.xxx.xxx.xxx/cctv2&lt;/link&gt;
				&lt;thumbnail&gt;http://xxx/cctv2.jpg&lt;/thumbnail&gt;
			&lt;/item&gt;
		&lt;/items&gt;
	&lt;/channel&gt;

	&lt;channel&gt;
		&lt;name&gt;Channel 2&lt;/name&gt;
		&lt;thumbnail&gt;http://xxx/chn2.png&lt;/thumbnail&gt;
		&lt;subchannels&gt;
			&lt;subchannel&gt;
				&lt;name&gt;Sub 1&lt;/name&gt;
				&lt;thumbnail&gt;http://xxx/sub1.png&lt;/thumbnail&gt;
				&lt;subitems&gt;
					&lt;subitem&gt;
						&lt;title&gt;Sub TV1&lt;/title&gt;
						&lt;link&gt;mms://xxx.xxx.xxx.xxx/subtv1&lt;/link&gt;
						&lt;thumbnail&gt;http://xxx/subtv1.jpg&lt;/thumbnail&gt;
					&lt;/subitem&gt;
					&lt;subitem&gt;
						&lt;title&gt;Sub TV2&lt;/title&gt;
						&lt;link&gt;mms://xxx.xxx.xxx.xxx/subtv2&lt;/link&gt;
						&lt;thumbnail&gt;http://xxx/subtv2.jpg&lt;/thumbnail&gt;
					&lt;/subitem&gt;
				&lt;/subitems&gt;
			&lt;/subchannel&gt;
		&lt;/subchannels&gt;
	&lt;/channel&gt;
&lt;/channels&gt;
</pre>
<p>第一个节目目录 Channel 1 下面没有子目录，只有 TV1 和 TV2 这两个节目，因此 XML 层次是 <strong>channel/items/item</strong>。第二个节目目录 Channel 2 下有名为 Sub1 的子目录，Sub1 下又有 Sub TV1 和 Sub TV2 两个节目，这种的 XML 层次则是：<strong>channel/subchannels/subchannel/subitems/subitem</strong>。</p>
<p>需要注意的是 LiveStreams 的 XML 配置文件必须以 UTF-8 编码格式保存，否则非英文字符将无法正常显示。另外由于 XML 本身格式的原因，XML 内容中的这些字符需要转换（全部为纯英文字符，包括结束的分号）：</p>
<p><strong><span style="color: #ff0000;">&amp;</span></strong> 转换为 <strong><span style="color: #ff0000;">&amp;amp;</span></strong><br />
<strong><span style="color: #ff0000;">&lt;</span></strong> 转换为 <strong><span style="color: #ff0000;">&amp;lt;</span></strong><br />
<strong><span style="color: #ff0000;">&gt;</span></strong> 转换为 <strong><span style="color: #ff0000;">&amp;gt;</span></strong><br />
<strong><span style="color: #ff0000;">'</span></strong> 转换为 <strong><span style="color: #ff0000;">&amp;apos;</span></strong><br />
<strong><span style="color: #ff0000;">"</span></strong> 转换为 <strong><span style="color: #ff0000;">&amp;quot;</span></strong></p>
<p>最后附上我修改过的最新 LiveStreams 1.0.6 版本 XBMC 插件的下载地址：</p>
<p><a href="http://miseal.googlecode.com/files/plugin.video.live.streams-1.0.6.zip" target="_blank">http://miseal.googlecode.com/files/plugin.video.live.streams-1.0.6.zip</a></p>
<p>由于这插件只是随便修改的，有任何问题欢迎指正哦。 ^_^</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/xbmc-livestreams-cn-patch/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
