init upload

This commit is contained in:
guyue 2024-08-01 19:38:07 +08:00
parent 38549643bd
commit 2fb1cf1c28
202 changed files with 12070 additions and 2 deletions

11
DONATE.md Normal file
View File

@ -0,0 +1,11 @@
如果觉得SoulBook对您有帮助那么您可以给开发者一些支持
- 开源
- 服务器的费用也是一笔开销
- 为用户提供更好的搜索环境
- 一杯咖啡
请扫一扫微信支付(留言希望你带上自己的名字^_^
<img src="https://ws1.sinaimg.cn/large/007i3XCUgy1fydjg9e5fsj30lq0lmgoj.jpg" width = "400" height = "400" alt="donate" align=center />

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
# 基于python3.6镜像来构建owllook镜像
FROM python:3.6
MAINTAINER howie6879 <howie6879@gmail.com>
ENV TIME_ZONE=Asia/Shanghai
RUN echo "${TIME_ZONE}" > /etc/timezone \
&& ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime
ADD . /owllook
WORKDIR /owllook
RUN pip install --no-cache-dir --trusted-host mirrors.aliyun.com -i http://mirrors.aliyun.com/pypi/simple/ pipenv
RUN pipenv install --skip-lock
RUN find . -name "*.pyc" -delete

13
HISTORY.md Normal file
View File

@ -0,0 +1,13 @@
## 更新历史记录
### 0.1.0 / 2017-03-05
---
- 小说的基本搜索解析功能
- 搜索记录
- 缓存
- 书架
- 书签
- 登录(暂时不开放注册,可与我申请体验)
- 初步兼容手机(后续跟进)

201
LICENSE.txt Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 howie.hu
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

35
Pipfile Normal file
View File

@ -0,0 +1,35 @@
[[source]]
verify_ssl = true
name = "pypi"
url = "https://pypi.douban.com/simple/"
[requires]
python_version = "3.6"
[dev-packages]
[packages]
aiohttp = "*"
arrow = "*"
async_timeout = "*"
"bs4" = "*"
cchardet = "*"
gunicorn = "*"
"html5lib" = "*"
Jinja2 = "==2.11.3"
motor = "==1.1"
numpy = "*"
requests = ">=2.20.0"
Sanic = "==0.5.1"
sanic_session = "==0.1.2"
schedule = "*"
uvloop = "*"
pytest = "*"
pymongo = "*"
aiofiles = "*"
pyquery = "*"
ruia-ua = "*"
ruia = ">=0.5.8"
aiocache = "==0.3.2"
aioredis = "==0.3.3"
asyncio_redis = "==0.14.3"

184
README.md
View File

@ -1,2 +1,182 @@
# SoulBook ## 基于大佬的项目修改
在线(解析)阅读小说 早先使用时基于大佬的项目owllook做了一点点修改更贴近自己的习惯最近有空正好上传下方便闲暇时优化原说明在下面。
## owllook - 在线小说搜索引擎
[![Python3.6+](https://img.shields.io/badge/python-3.6%2B-orange.svg)](https://github.com/howie6879/owllook) [![license](https://img.shields.io/github/license/howie6879/owllook.svg)](https://github.com/howie6879/owllook)
`owllook`是一个基于其他搜索引擎构建的垂直小说搜索引擎owllook目的是让阅读更简单、优雅让每位读者都有舒适的阅读体验如**搜书、阅读、收藏、追更、推荐等功能**
- ~~演示网址(不维护了,有兴趣自己搭建)~~[https://www.owllook.net/](https://www.owllook.net/)
- 公众号:[**粮草小说**](https://www.owllook.net/static/novels/img/lcxs_show.jpg),有兴趣的话可以关注下
- 详细安装介绍:[详细安装介绍](https://mp.weixin.qq.com/s/0CqLiKsyDQ-pVmeo3R-UlA)
- 个人公众号:[老胡的储物柜](https://raw.githubusercontent.com/howie6879/howie6879.github.io/img/pictures/20190529083905.png)
<div align=center><img width="400" height="400" src="https://raw.githubusercontent.com/howie6879/howie6879.github.io/img/pictures/20190529083905.png" /></div>
衍生项目:
- 终端看小说: [NIYT](https://github.com/howie6879/NIYT)
- 小说监控工具:[owllook_gui](https://github.com/howie6879/owllook_gui)
- 小说接口:[owllook_api](https://github.com/howie6879/owllook_api)
**注意**:若将本项目部署并发行,请**声明来源**,本项目纯属**共享学习之用,不得用于商业!**
### Overview
`owllook`使用了mongodb储存了用户使用过程中的产生的基本信息诸如注册信息、搜索小说信息、收藏小说数据等对于某些必要的缓存则利用redis进行缓存处理如小说缓存、session缓存注意对于限制数据都将在24小时删除
对于不同网站的小说,页面规则都不尽相同,我希望能够在代码解析后再统一展示出来,这样方便且美观,而不是仅仅跳转到对应网站就完事,清新简洁的阅读体验才是最重要的
目前采用的是直接在搜索引擎上进行结果检索,我尽量写少量的规则来完成解析,具体见[规则定义](./docs/规则定义.md),遇到自己喜欢的小说网站,你也可以自己添加解析,`owllook`目前解析了超过 **200+** 网站,追更网站解析了**50+**
有一些地方需要用到爬虫比如说排行榜一些书籍信息等我不想动用重量级爬虫框架来写于是我在owllook里面编写了一个很轻量的爬虫框架来做这件事**[ruia](https://github.com/howie6879/ruia)**
BTWsanic写界面确实不是很方便至于为什么写这个一是想利用`sanic`尽量做成异步服务,二是想就此练习下推荐系统,顺便作为毕业设计
#### Installation
请先装好mongo以及redis不会安装mongo看[这里](https://www.digitalocean.com/community/tutorials/how-to-install-mongodb-on-centos-7)`owllook`使用`pipenv`管理虚拟环境,所以使用前请确保安装一个`Python3.6`环境(比如我这里环境路径在`/Users/howie/anaconda3/envs/python36/bin/python3.6`),然后安装好`pipenv`
mongo以及redis装好后进入项目目录依照步骤执行
```shell
# 下载代码
git clone https://github.com/howie6879/owllook
cd owllook
pip install pipenv
# 请先提前创建好Python3.6环境
pipenv install --python /Users/howie/anaconda3/envs/python36/bin/python3.6 --skip-lock
# 进入虚拟环境
pipenv shell
# 先配置好相关数据库配置,具体看`config/dev_config.py`
# 方案一
# 运行:
cd owllook
pipenv run gunicorn -c owllook/config/gunicorn.py --worker-class sanic.worker.GunicornWorker owllook.server:app
# 方案二 推荐
# 安装docker并打包镜像
docker build -t howie6879/owllook .
# 实际运行
docker-compose up -d
# 退出
docker-compose down
```
#### Features
- 多搜索源
- 丰富的解析源
- 界面统一解析
- 完善的阅读体验
- 搜索记录
- 缓存
- 书架
- 书签
- 登录
- 初步兼容手机(后续跟进)
- 注册(开放注册)
- 上次阅读记录
- 最新章节
- 书友推荐(简单地基于相似度进行推荐)
- 目录获取
- 翻页
- 搜索排行
- 章节异步加载 感谢@[mscststs](https://github.com/mscststs)
- 排行榜 - 起点+owllook
- 自带爬虫框架,统一爬虫规范,对爬虫感兴趣的可以看看 - [ruia](https://github.com/howie6879/ruia)
#### TODO
- [ ] 评分
- [ ] 阅读书单
- [ ] 推荐
- [ ] 小说圈 - 小说界的消息
### Screenshots
首页:
![](https://ws1.sinaimg.cn/large/007i3XCUgy1fynmmhyim2j31hc0r140i.jpg)
搜索:
![](https://ws1.sinaimg.cn/large/007i3XCUgy1fynmkbqzf3j31h70qz42y.jpg)
榜单:
![](https://ws1.sinaimg.cn/large/007i3XCUgy1fynmdwg8tpj31gv0qt42e.jpg)
书架:
![books](./docs/imgs/book.jpeg)
目录解析页:
![demo](./docs/imgs/chapter.png)
阅读:
![content](./docs/imgs/content.png)
### FAQ
**为什么首页榜单为空白?**
这个是根据小说搜索次数显示的,每天刷新一次,使用多了就会有
**为什么会出现302跳转**
为了防止直接运行服务被恶意域名绑定,所以作出如下修改:
```shell
vim config/config.py
# 将 true 改为 false
VAL_HOST = os.getenv('VAL_HOST', 'true')
VAL_HOST = os.getenv('VAL_HOST', 'false')
```
**小说榜单页面为什么没有内容?**
需要运行`owllook/spiders/spider_console.py`
目前代码中是设定60分钟运行一次运行的时候请酌情更改
`os.environ['MODE'] = 'PRO'` 这段代码也请注释掉
### Reference
**owllook使用了以下第三方包:**
- sanic基于Python 3.5+的异步web服务器
- motor异步的mongodb驱动
- Jinja2基于python的模板引擎
- aiohttp异步请求
- caddy基于go的web服务器
…...更多见Pipfile感谢开发者
**web框架**
- [bootstrap](https://github.com/twbs/bootstrap)Sleek, intuitive, and powerful front-end framework for faster and easier web development.
- [mdui](https://github.com/zdhxiong/mdui )MDUI 是一个基于 Material Design 的前端框架
### License
`owllook` is offered under the Apache 2 license.
### Donate
**捐赠:**
> 美酒加咖啡,我只要喝一杯~
<img src="https://raw.githubusercontent.com/howie6879/howie6879.github.io/img/pictures/20190904201512.png" width = "400" height = "400" alt="donate" align=center />
感谢以下捐赠者,具体见[捐赠名单](./DONATE.md) ^_^

11
__init__.py Normal file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env python
"""
Created by howie.hu at 17-9-22.
"""
from sys import path as path_sys
from os import path as path_os
# from multiprocessing.managers import BaseManager
# from multiprocessing import freeze_support
# environment variable
path_sys.append(path_os.dirname(__file__))

9
docker-compose.yml Normal file
View File

@ -0,0 +1,9 @@
version: '3'
services:
web:
image: howie6879/owllook
command: pipenv run gunicorn -c soulbook/config/gunicorn.py --worker-class sanic.worker.GunicornWorker soulbook.server:app
ports:
- "8001:8001"
volumes:
- .:/soulbook

BIN
docs/imgs/book.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

BIN
docs/imgs/chapter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

BIN
docs/imgs/content.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
docs/imgs/similar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

102
docs/简介.md Normal file
View File

@ -0,0 +1,102 @@
![owllook-demo](http://oe7yjec8x.bkt.clouddn.com/howie/2017-03-08-owllook.gif)
## 0.前言
事情的起因是这样的,前段时间在把之前写的一些同步网络请求代码改成异步的,用的是`aiohttp`,既然是请求,那请求什么呢,就百度吧,请求什么内容呢,我随手一输自己最近看的一本小说,然后作为练手用,就做了这个,我将其取名为`owllook`,准备做成一个推荐系统,所以我就将其部署上去,这才有了这个网站。
上一篇介绍了自己在使用`sanic`过程中遇到的一些问题,这次就想介绍下这个[owllook--novels_search](https://github.com/howie6879/novels-search)上面是演示demo具体可以见[http://www.owllook.net/](http://www.owllook.net/)
**本项目纯属共享学习之用,不得用于商业!**
首先我想说下目前的项目进度:
v0.1已经上线:
- 小说的基本搜索解析功能
- 搜索记录
- 缓存
- 书架
- 书签
- 登录(**暂时不开放注册,可与我申请体验**
TODO:
- [ ] 注册
- [ ] 阅读书单
- [ ] 手机端兼容
- [ ] 推荐
- [ ] 排行榜
- [ ] 个人中心
## 1.介绍
`owllook`的思路很简单,利用百度检索出来的结果,进行过滤解析后再展示,使用的技术如下:
- sanic基于Python 3.5+的异步web服务器快快快
- sanic_sessionsanic的持续会话插件
- vloopsanic默认使用uvloop替代asyncio本身的loop
- motor异步的mongodb驱动
- aiohttp异步请求
- aiocache异步缓存本项目改用了其中的decorator部分缓存数据库使用redis
对于用户的一系列操作信息,使用`mongodb`进行存储,而缓存则使用`redis`。
对于不同网站的小说,页面规则都不尽相同,我希望能够在代码解析后再统一展示出来,这样方便且美观,而不是仅仅跳转到对应网站就完事,清新简洁的阅读体验才是最重要的。
目前采用的是直接在百度上进行结果检索,也不是不能做的更大更全,只是觉得没什么意义,目前的检索结果已经很足够。
我尽量写少量的规则来完成解析,具体见[规则定义](https://github.com/howie6879/novels-search/blob/master/docs/%E8%A7%84%E5%88%99%E5%AE%9A%E4%B9%89.md),遇到自己喜欢的小说网站,方便诸位添加解析。
一般都是在下班时间编写这个项目,目前`v0.1`版本大概实现。
后期我准备将基础功能写好之后能够实现小说与kindle之间的对接。
## 2.解析
这个项目的思路与技术都比较简单,但是小说网站的解析工作是很难全部解析完毕,下面我将举个例子怎么具体的解析一个网站,欢迎各位添砖加瓦,请先看一遍[规则定义](https://github.com/howie6879/novels-search/blob/master/docs/%E8%A7%84%E5%88%99%E5%AE%9A%E4%B9%89.md)。
解析也很简单只要求有点html以及css基础即可。
首先进入网站http://www.owllook.net/。
搜索:
![01](http://oe7yjec8x.bkt.clouddn.com/howie/2017-03-10-01.png-blog.howie)
注意第一条结果显示未解析,这就是我们要解析的对象了,点击进入源网站,审查小说目录对应的元素,这里显示的是:`class="mulu_list`,然后注意其`content_url`类型是`0`
![02](http://oe7yjec8x.bkt.clouddn.com/howie/2017-03-10-02.png-blog.howie)
进入小说章节内容页面,审查元素可以看到`id=htmlContent`,所以`content_selector=htmlContent`
接下来进入项目,打开`config/rules.py`文件在RULES字典中加入
``` python
'www.ybdu.com': Rules('0', {'class': 'mulu_list'}, {'id': 'htmlContent'}),
```
这时候再重启服务,刷新页面:
![03](http://oe7yjec8x.bkt.clouddn.com/howie/2017-03-10-03.png-blog.howie)
可以看到未解析变成了已解析,这时候点击进入,会出现两种情况:
- 排版完整,不需要再写样式,此时请直接解析章节内容
- 排版不行,需要写样
现在我演示的这个链接排版就是显示不行,请打开`/static/novels/css/chapter.css`文件,在编写之前,请先看下面这张图:
![04](http://oe7yjec8x.bkt.clouddn.com/howie/2017-03-10-04.jpeg-blog.howie)
图中.mulu_list1打错了表示区域1.mulu_list1表示区域3.
首先更改区域1的样式我已经在代码注释写了各个区域样式代码在哪直接更改就行比如
``` css
/* 区域1 */
.mulu_list, .acss, .list, #xslist ul, .dirlist, .list-chapter, .list_box ul, #defaulthtml4 table, .article-list > dl, .update, #list .box, .bookcontent > dl, .listmain > dl, .ml_main > dl, #list dl, #chapter_list, .chapterlist, tbody, .mt10, .catalog, #readerlists {
float: left;
overflow: hidden;
padding-bottom: 1px;
margin: auto;
background: #F6F4EC;
border-radius: 15px;
}
```
可以看到加上了`.mulu_list`,以此类推,最后解析完毕之后如下图:
![05](http://oe7yjec8x.bkt.clouddn.com/howie/2017-03-10-05.png-blog.howie)
注意章节内容里面一些无关的链接以及原本网页自带的上一章下一章需要隐藏掉哦。
## 3.总结
功能还很简单,解析的网站有很多,希望各位添砖加瓦,容我奉上项目地址:[owllook--novels_search](https://github.com/howie6879/novels-search)
**仅供分享交流 不可用于商业用途**

64
docs/规则定义.md Normal file
View File

@ -0,0 +1,64 @@
## 规则定义说明:
对于各类小说网站的解析,只需按照这个要求进行定义,解析便会尽量自动进行,总规则如下:
```python
# 在项目下config/config.py文件中可以看到
Rules = namedtuple('Rules', 'content_url chapter_selector content_selector')
# 在自定义字典RULES下面可以看到各个网站的规则仅限class和id
# demo 'name': Rules('content_url', {chapter_selector}, {content_selector})
```
对于各个`namedtuple`里面的`content_urlchapter_selectorcontent_selector`,下面通过不同类型的网站一一进行解释:
- http://www.bxwx9.org/b/57/57181/
打开这个网站,审查元素后你会发现:
- url输入栏显示内容为`http://www.bxwx9.org/b/57/57181/`
- 主要内容包含在`.TabCss`内
- 第一章的href值为`8845907.html`,由此可知该章的链接为`http://www.bxwx9.org/b/57/57181/8845907.html`
最后写出规则:
```python
RULES={
'www.bxwx9.org': Rules('0', {'class': 'TabCss'}, {})
}
```
`key`值起判断该网站是否被解析,注意此时`content_url`为0这是表示在解析小说目录的时候每章节对应的url在拼接过程中需要的是当前的url。对于`content_url`,请看下表:
| 值 | 说明 |
| :----: | :------------------: |
| -1 | 不解析,跳转到原本网页 |
| 0 | 表示章节网页需要当前页面url拼接 |
| 1 | 表示章节链接使用本身自带的链接,不用拼接 |
| netloc | 用域名进行拼接 |
`chapter_selector`解析章节目录的规则
`content_selector`解析目录内容的规则
- http://www.23us.la/html/0/42/
```python
RULES={
'www.23us.la': Rules('http://www.23us.la', {'class': 'inner'}, {})
}
```
- http://zetianjiba.net
```python
RULES={
'zetianjiba.net': Rules('1', {'class': 'bg'}, {})
}
```
`content_selector`值的获取方式同上

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python
import asyncio
import os
import time
import uvloop
from pprint import pprint
os.environ['MODE'] = 'PRO'
from soulbook.fetcher.cache import get_the_latest_chapter, update_all_books
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
def latest_chapter_task(url):
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(get_the_latest_chapter(url))
loop.run_until_complete(task)
return task.result()
def update_all():
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(update_all_books())
loop.run_until_complete(task)
return task.result()
start = time.time()
chapter_url = "/chapter?url=http://www.8535.org/xuanhuan/139075/&novels_name=圣墟"
result = latest_chapter_task(chapter_url)
pprint(result)
print(time.time() - start)

View File

@ -0,0 +1,173 @@
#!/usr/bin/env python
import aiohttp
import arrow
import asyncio
import async_timeout
import re
from bs4 import BeautifulSoup
from urllib.parse import urlparse
from soulbook.fetcher.function import get_random_user_agent
from soulbook.config import CONFIG, LOGGER, BLACK_DOMAIN, RULES, LATEST_RULES
async def fetch(client, url, name, is_web):
with async_timeout.timeout(15):
try:
headers = {'user-agent': await get_random_user_agent()}
if is_web:
params = {'wd': name, 'ie': 'utf-8', 'rn': CONFIG.BAIDU_RN, 'vf_bl': 1}
else:
params = {'word': name}
async with client.get(url, params=params, headers=headers) as response:
assert response.status == 200
LOGGER.info('Task url: {}'.format(response.url))
try:
text = await response.text()
except:
text = await response.read()
return text
except Exception as e:
LOGGER.exception(e)
return None
async def get_real_url(client, url):
with async_timeout.timeout(5):
try:
headers = {'user-agent': await get_random_user_agent()}
async with client.head(url, headers=headers, allow_redirects=True) as response:
assert response.status == 200
LOGGER.info('Parse url: {}'.format(response.url))
# text = ""
# try:
# text = await response.text()
# except:
# text = await response.read()
# if text:
# print(text)
# text = re.findall(r'replace\(\"(.*?)\"\)', str(text))
# text = text[0] if text[0] else ""
url = response.url if response.url else None
return url
except Exception as e:
LOGGER.exception(e)
return None
async def data_extraction_for_phone(html):
with async_timeout.timeout(10):
try:
# Get title
data_log = eval(html['data-log'])
url = data_log.get('mu', None)
if not url:
return None
# Get title
title = html.find('h3').get_text()
# Get author and update_time (option)
novel_mess = html.findAll(class_='c-gap-right-large')
basic_mess = [i.get_text() for i in novel_mess] if novel_mess else None
return {'title': title, 'url': url, 'basic_mess': basic_mess}
except Exception as e:
LOGGER.exception(e)
return None
async def data_extraction_for_web(html):
with async_timeout.timeout(10):
try:
url = html.find('a').get('href', None)
if not url or 'baidu' in url or urlparse(url).netloc in BLACK_DOMAIN:
return None
netloc = urlparse(url).netloc
is_parse = 1 if netloc in RULES.keys() else 0
title = html.select('font[size="3"]')[0].get_text()
source = html.select('font[color="#008000"]')[0].get_text()
time = re.findall(r'\d+-\d+-\d+', source)
time = time[0] if time else None
timestamp = 0
if time:
try:
time_list = [int(i) for i in time.split('-')]
timestamp = arrow.get(time_list[0], time_list[1], time_list[2]).timestamp
except Exception as e:
LOGGER.exception(e)
timestamp = 0
return {'title': title, 'url': url.replace('index.html', '').replace('Index.html', ''), 'time': time,
'is_parse': is_parse,
'timestamp': timestamp,
'netloc': netloc}
except Exception as e:
LOGGER.exception(e)
return None
async def data_extraction_for_web_baidu(client, html):
with async_timeout.timeout(20):
try:
url = html.select('h3.t a')[0].get('href', None)
real_url = await get_real_url(client=client, url=url) if url else None
if real_url:
real_str_url = str(real_url)
netloc = urlparse(real_str_url).netloc
if "http://" + netloc + "/" == real_str_url:
return None
if 'baidu' in real_str_url or netloc in BLACK_DOMAIN:
return None
is_parse = 1 if netloc in RULES.keys() else 0
title = html.select('h3.t a')[0].get_text()
is_recommend = 1 if netloc in LATEST_RULES.keys() else 0
# time = re.findall(r'\d+-\d+-\d+', source)
# time = time[0] if time else None
timestamp = 0
time = ""
# if time:
# try:
# time_list = [int(i) for i in time.split('-')]
# timestamp = arrow.get(time_list[0], time_list[1], time_list[2]).timestamp
# except Exception as e:
# LOGGER.exception(e)
# timestamp = 0
return {'title': title, 'url': real_str_url.replace('index.html', ''), 'time': time,
'is_parse': is_parse,
'is_recommend': is_recommend,
'timestamp': timestamp,
'netloc': netloc}
else:
return None
except Exception as e:
LOGGER.exception(e)
return None
async def baidu_search(name, is_web=1):
url = CONFIG.URL_PC if is_web else CONFIG.URL_PHONE
async with aiohttp.ClientSession() as client:
html = await fetch(client=client, url=url, name=name, is_web=is_web)
if html:
soup = BeautifulSoup(html, 'html5lib')
if is_web:
# result = soup.find_all(class_='f')
result = soup.find_all(class_='result')
extra_tasks = [data_extraction_for_web_baidu(client=client, html=i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
else:
result = soup.find_all(class_='result c-result c-clk-recommend')
extra_tasks = [data_extraction_for_phone(i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
# return await asyncio.gather(*tasks)
done_list, pending_list = await asyncio.wait(tasks)
res = []
for task in done_list:
res.append(task.result())
return res
if __name__ == '__main__':
import time
start = time.time()
print(asyncio.get_event_loop().run_until_complete(baidu_search('雪中悍刀行')))
print(time.time() - start)

View File

@ -0,0 +1,114 @@
#!/usr/bin/env python
"""
Created by howie.hu at 21/11/2017.
"""
import aiohttp
import asyncio
import async_timeout
from bs4 import BeautifulSoup
from urllib.parse import urlparse
from soulbook.fetcher.function import get_random_user_agent
from soulbook.config import CONFIG, LOGGER, BLACK_DOMAIN, RULES, LATEST_RULES
async def fetch(client, url, novels_name):
with async_timeout.timeout(20):
try:
headers = {
'user-agent': await get_random_user_agent(),
'referer': "https://www.bing.com/"
}
print(headers)
params = {'q': novels_name, 'ensearch': 0}
async with client.get(url, params=params, headers=headers) as response:
assert response.status == 200
LOGGER.info('Task url: {}'.format(response.url))
try:
text = await response.text()
except:
text = await response.read()
return text
except Exception as e:
LOGGER.exception(e)
return None
async def data_extraction_for_web_bing(client, html):
with async_timeout.timeout(15):
try:
try:
title = html.select('h2 a')[0].get_text()
url = html.select('h2 a')[0].get('href', None)
netloc = urlparse(url).netloc
url = url.replace('index.html', '').replace('Index.html', '')
if not url or 'baidu' in url or 'baike.so.com' in url or netloc in BLACK_DOMAIN or '.html' in url:
return None
is_parse = 1 if netloc in RULES.keys() else 0
is_recommend = 1 if netloc in LATEST_RULES.keys() else 0
# time = html.select('div.b_attribution')[0].get_text()
# time = re.findall(r'\d+-\d+-\d+', time)
# time = time[0] if time else ''
timestamp = 0
time = ''
# if time:
# try:
# time_list = [int(i) for i in time.split('-')]
# years = str(time_list[0])[-4:]
# timestamp = arrow.get(int(years), time_list[1], time_list[2]).timestamp
# time = years + "-" + str(time_list[1]) + "-" + str(time_list[2])
# except Exception as e:
# LOGGER.exception(e)
# timestamp = 0
return {'title': title,
'url': url,
'time': time,
'is_parse': is_parse,
'is_recommend': is_recommend,
'timestamp': timestamp,
'netloc': netloc}
except Exception as e:
LOGGER.exception(e)
url, title = None, None
return None
except Exception as e:
LOGGER.exception(e)
return None
async def bing_search(novels_name):
url = CONFIG.BY_URL
async with aiohttp.ClientSession() as client:
html = await fetch(client=client, url=url, novels_name=novels_name)
if html:
soup = BeautifulSoup(html, 'html5lib')
result = soup.find_all(class_='b_algo')
extra_tasks = [data_extraction_for_web_bing(client=client, html=i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
return await asyncio.gather(*tasks)
else:
return []
if __name__ == '__main__':
import uvloop
import time
from pprint import pprint
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
def novel_task(name):
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(bing_search(name))
loop.run_until_complete(task)
return task.result()
start = time.time()
result = novel_task('牧神记 小说 阅读 最新章节')
pprint(result)
print(time.time() - start)

View File

@ -0,0 +1,106 @@
#!/usr/bin/env python
"""
Created by howie.hu at 23/11/2017.
"""
import aiohttp
import asyncio
import async_timeout
from bs4 import BeautifulSoup
from urllib.parse import parse_qs, urlparse
from soulbook.fetcher.function import get_random_user_agent
from soulbook.config import CONFIG, LOGGER, BLACK_DOMAIN, RULES, LATEST_RULES
async def fetch(client, url, novels_name):
with async_timeout.timeout(20):
try:
headers = {
'user-agent': await get_random_user_agent(),
'referer': "https://duckduckgo.com/"
}
params = {'q': novels_name}
# , proxy="http://127.0.0.1:8118"
async with client.get(url, params=params, headers=headers) as response:
assert response.status == 200
LOGGER.info('Task url: {}'.format(response.url))
try:
text = await response.text()
except:
text = await response.read()
return text
except Exception as e:
LOGGER.exception(e)
return None
async def data_extraction_for_web_duck(client, html):
with async_timeout.timeout(15):
try:
try:
title = html.select('h2 a')[0].get_text()
url = html.select('h2 a')[0].get('href', None)
url = parse_qs(url).get('uddg', ['#'])[0]
netloc = urlparse(url).netloc
url = url.replace('index.html', '').replace('Index.html', '')
if not url or 'baidu' in url or 'baike.so.com' in url or netloc in BLACK_DOMAIN or '.html' in url:
return None
is_parse = 1 if netloc in RULES.keys() else 0
is_recommend = 1 if netloc in LATEST_RULES.keys() else 0
# time = html.select('div.b_attribution')[0].get_text()
# time = re.findall(r'\d+-\d+-\d+', time)
# time = time[0] if time else ''
timestamp = 0
time = ''
return {'title': title,
'url': url,
'time': time,
'is_parse': is_parse,
'is_recommend': is_recommend,
'timestamp': timestamp,
'netloc': netloc}
except Exception as e:
LOGGER.exception(e)
url, title = None, None
return None
except Exception as e:
LOGGER.exception(e)
return None
async def duck_search(novels_name):
url = CONFIG.DUCKGO_URL
async with aiohttp.ClientSession() as client:
html = await fetch(client=client, url=url, novels_name=novels_name)
if html:
soup = BeautifulSoup(html, 'html5lib')
result = soup.find_all(class_='result')
extra_tasks = [data_extraction_for_web_duck(client=client, html=i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
return await asyncio.gather(*tasks)
else:
return []
if __name__ == '__main__':
import uvloop
import time
from pprint import pprint
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
def novel_task(name):
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(duck_search(name))
loop.run_until_complete(task)
return task.result()
start = time.time()
result = novel_task('圣墟 小说 阅读 最新章节')
pprint(result)
print(time.time() - start)

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python
import asyncio
import os
import uvloop
os.environ['MODE'] = 'PRO'
from soulbook.fetcher.cache import update_all_books
def update_all():
# asyncio.get_event_loop().run_until_complete(update_all_books())
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(update_all_books(loop=loop, timeout=15))
loop.run_until_complete(task)
return task.result() or None
if __name__ == '__main__':
print(update_all())

26
examples/novels/parse.py Normal file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env python
import aiohttp
import asyncio
import time
import uvloop
from pprint import pprint
from soulbook.fetcher.function import target_fetch
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
def novel_task(url):
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(target_fetch(url, {}))
loop.run_until_complete(task)
return task.result()
start = time.time()
# result = novel_task('http://www.shuge.net/html/98/98044')
result = novel_task('http://www.biqugexsw.com/1_1020/')
pprint(result)
print(time.time() - start)

View File

@ -0,0 +1,119 @@
#!/usr/bin/env python
import aiohttp
import asyncio
import async_timeout
from bs4 import BeautifulSoup
from urllib.parse import parse_qs, urlparse
from soulbook.fetcher.function import get_random_user_agent
from soulbook.config import CONFIG, LOGGER, BLACK_DOMAIN, RULES, LATEST_RULES
async def fetch(client, url, novels_name):
with async_timeout.timeout(20):
try:
headers = {
'User-Agent': await get_random_user_agent(),
'Referer': "http://www.so.com/haosou.html?src=home"
}
params = {'ie': 'utf-8', 'src': 'noscript_home', 'shb': 1, 'q': novels_name, }
async with client.get(url, params=params, headers=headers) as response:
assert response.status == 200
LOGGER.info('Task url: {}'.format(response.url))
try:
text = await response.text()
except:
text = await response.read()
return text
except Exception as e:
LOGGER.exception(e)
return None
async def data_extraction_for_web_so(client, html):
with async_timeout.timeout(15):
try:
# 2017.09.09 修改 更加全面地获取title && url
try:
title = html.select('h3 a')[0].get_text()
url = html.select('h3 a')[0].get('href', None)
except Exception as e:
LOGGER.exception(e)
url, title = None, None
return None
# 针对不同的请进行url的提取
if "www.so.com/link?m=" in url:
url = html.select('h3 a')[0].get('data-url', None)
if "www.so.com/link?url=" in url:
url = parse_qs(urlparse(url).query).get('url', None)
url = url[0] if url else None
# try:
# url = html.select('h3.res-title a')[0].get('data-url', None)
# title = html.select('h3.res-title a')[0].get_text()
# except IndexError:
# url = html.select('h3.title a')[0].get('href', None)
# url = parse_qs(urlparse(url).query).get('url', None)
# url = url[0] if url else None
# title = html.select('h3.title a')[0].get_text()
# except Exception as e:
# LOGGER.exception(e)
# url, title = None, None
# return None
# 2017.07.09 此处出现bug url展示形式发生变化 因此对于h3.title a形式依旧不变 但是h3.res-title a则取属性data-url
# url = parse_qs(urlparse(url).query).get('url', None)
# url = url[0] if url else None
netloc = urlparse(url).netloc
if not url or 'baidu' in url or 'baike.so.com' in url or netloc in BLACK_DOMAIN:
return None
is_parse = 1 if netloc in RULES.keys() else 0
is_recommend = 1 if netloc in LATEST_RULES.keys() else 0
time = ''
timestamp = 0
return {'title': title, 'url': url.replace('index.html', '').replace('Index.html', ''), 'time': time,
'is_parse': is_parse,
'is_recommend': is_recommend,
'timestamp': timestamp,
'netloc': netloc}
except Exception as e:
LOGGER.exception(e)
return None
async def so_search(novels_name):
url = CONFIG.SO_URL
async with aiohttp.ClientSession() as client:
html = await fetch(client=client, url=url, novels_name=novels_name)
if html:
soup = BeautifulSoup(html, 'html5lib')
result = soup.find_all(class_='res-list')
extra_tasks = [data_extraction_for_web_so(client=client, html=i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
return await asyncio.gather(*tasks)
else:
return []
if __name__ == '__main__':
import uvloop
import time
from pprint import pprint
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
def novel_task(name):
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(so_search(name))
loop.run_until_complete(task)
return task.result()
start = time.time()
result = novel_task('圣墟 小说 阅读 最新章节')
pprint(result)
print(time.time() - start)

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
import asyncio
import collections
import os
from operator import itemgetter
import uvloop
os.environ['MODE'] = 'DEV'
from pprint import pprint
from copy import deepcopy
from soulbook.database.mongodb import MotorBase
from soulbook.recommend.cosinesimilarity import CosineSimilarity
from soulbook.fetcher.function import get_time
async def get_user_tag():
motor_db = MotorBase().get_db()
user_tag_cursor = motor_db.user_tag.find({}, {'data': 1, 'user': 1, '_id': 0})
result = {}
user_book_dict = {}
async for document in user_tag_cursor:
if document['data']:
user_book_dict[document['user'].replace('.', '&#183;')] = document['data']
result[document['user'].replace('.', '&#183;')] = document['data']['user_tag']
for key, value in result.items():
if not value:
continue
print("\nUser:", key)
print("User tags:", set(value))
print("User books:", user_book_dict[key]["user_novels"])
result_copy = deepcopy(result)
del result_copy[key]
cos = CosineSimilarity(value, result_copy)
vector = cos.create_vector()
resultDic = cos.calculate(vector)
print("相似用户:")
pprint(resultDic[:10])
# pprint(type(resultList[1]))
booksDic = collections.defaultdict(float)
for userBooks in resultDic:
for simuser, simrate in userBooks.items():
# print(simuser, simrate)
for book in user_book_dict[simuser]["user_novels"]:
booksDic[book] += simrate
# print(booksDic)
# 推荐20本书注意这里的推荐并没有去除用户收藏的书籍
recommend = sorted(booksDic.items(), key=itemgetter(1), reverse=True)[0:20]
print("书籍推荐:")
pprint(recommend)
recommend_novels = [book for book, simrate in recommend]
await motor_db.user_recommend.update_one(
{"user": key},
{'$set': {'similar_user': resultDic, 'user_tag': result[key], 'recommend_novels': recommend_novels,
"updated_at": get_time()}}, upsert=True)
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
def get_user_tag_test():
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(get_user_tag())
loop.run_until_complete(task)
return task.result()
if __name__ == '__main__':
get_user_tag_test()

90
examples/user_tag.py Normal file
View File

@ -0,0 +1,90 @@
#!/usr/bin/env python
import asyncio
import os
import pymongo
import uvloop
os.environ['MODE'] = 'PRO'
from pprint import pprint
from urllib.parse import parse_qs, urlparse
from soulbook.database.mongodb import MotorBase
from soulbook.fetcher.function import get_time
# mongo
MONGODB_SERVER = "localhost"
MONGODB_PORT = 27017
MONGODB_USERNAME = ""
MONGODB_PASSWORD = ""
MONGODB_DB = "soulbook"
MONGODB_COLLECTION = "all_novels_info"
class Novels(object):
def __init__(self):
_mongo_uri = 'mongodb://{account}{host}:{port}/{database}'.format(
account='{username}:{password}@'.format(
username=MONGODB_USERNAME,
password=MONGODB_PASSWORD) if MONGODB_USERNAME else '',
host='localhost',
port=27017,
database=MONGODB_DB)
connection = pymongo.MongoClient(_mongo_uri)
db = connection[MONGODB_DB]
self.collection = db[MONGODB_COLLECTION]
self.result_dict = dict()
def search_name(self, name):
if name in self.result_dict:
return self.result_dict[name] if self.result_dict[name] else False
result = self.collection.find_one({'novel_name': name})
if not result:
self.result_dict[name] = False
return False
self.result_dict[name] = {'author': result['author'], 'novels_type': result['novels_type'].split('#')}
return self.result_dict[name]
async def get_tag():
motor_db = MotorBase().get_db()
novels = Novels()
# 获取所有书架链接游标
books_url_cursor = motor_db.user_message.find({}, {'books_url.book_url': 1, 'user': 1, '_id': 0})
async for document in books_url_cursor:
if document:
books_url = document.get('books_url', None)
user = document['user']
if books_url:
all_user = {user + '_novels': [], user + '_tag': [], user + '_author': []}
for book_url in books_url:
chapter_url = book_url['book_url']
novels_name = parse_qs(urlparse(chapter_url).query).get('novels_name', '')[0]
all_user[user + '_novels'].append(novels_name)
novels_info = novels.search_name(novels_name)
if novels_info:
all_user[user + '_author'].append(novels_info['author'])
all_user[user + '_tag'].extend(novels_info['novels_type'])
data = {
'user_novels': all_user[user + '_novels'],
'user_tag': all_user[user + '_tag'],
'user_author': all_user[user + '_author'],
}
await motor_db.user_tag.update_one(
{"user": user},
{'$set': {'data': data, "updated_at": get_time()}}, upsert=True)
pprint(data)
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
def tag_test():
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(get_tag())
loop.run_until_complete(task)
return task.result()
if __name__ == '__main__':
tag_test()

67
requirements.txt Normal file
View File

@ -0,0 +1,67 @@
# sentry_sdk==1.5.10
# async_timeou
# requests>=2.20.0
# Sanic==0.5.1
# sanic_session==0.1.2
# pyquery
# asyncio_redis==0.14.3
aiocache==0.3.2
aiofiles==0.8.0
aiohttp==3.8.1
aiomcache==0.6.0
aioredis==0.3.3
aiosignal==1.2.0
arrow==1.2.2
async-timeout==4.0.2
asyncio-redis==0.14.3
asynctest==0.13.0
attrs==21.4.0
beautifulsoup4==4.11.1
bs4==0.0.1
cchardet==2.1.7
certifi==2021.10.8
charset-normalizer==2.0.12
cssselect==1.1.0
frozenlist==1.2.0
gunicorn==20.1.0
hiredis==2.0.0
html5lib==1.1
httptools==0.4.0
idna==3.3
idna-ssl==1.1.0
importlib-metadata==4.8.3
iniconfig==1.1.1
Jinja2==2.11.3
lxml==4.8.0
MarkupSafe==2.0.1
motor==1.1
multidict==5.2.0
numpy==1.19.5
packaging==21.3
pluggy==1.0.0
py==1.11.0
pymongo==3.4.0
pyparsing==3.0.8
pyquery==1.4.3
pytest==7.0.1
python-dateutil==2.8.2
requests==2.27.1
ruia==0.8.4
ruia-ua==0.0.2
sanic==0.5.1
sanic-session==0.1.2
schedule==1.1.0
sentry-sdk==1.5.10
six==1.16.0
soupsieve==2.3.2.post1
tomli==1.2.3
typing-extensions==4.1.1
ujson==4.3.0
urllib3==1.26.9
uvloop==0.14.0
webencodings==0.5.1
websockets==9.1
yarl==1.7.2
zipp==3.6.0

58
requirements2.txt Normal file
View File

@ -0,0 +1,58 @@
aiocache==0.3.2
aiofiles==0.8.0
aiohttp==3.8.1
aiomcache==0.6.0
aioredis==0.3.3
aiosignal==1.2.0
arrow==1.2.2
async-timeout==4.0.2
asyncio-redis==0.14.3
asynctest==0.13.0
attrs==21.4.0
beautifulsoup4==4.11.1
bs4==0.0.1
cchardet==2.1.7
certifi==2021.10.8
charset-normalizer==2.0.12
cssselect==1.1.0
frozenlist==1.2.0
gunicorn==20.1.0
hiredis==2.0.0
html5lib==1.1
httptools==0.4.0
idna==3.3
idna-ssl==1.1.0
importlib-metadata==4.8.3
iniconfig==1.1.1
Jinja2==2.11.3
lxml==4.8.0
MarkupSafe==2.0.1
motor==1.1
multidict==5.2.0
numpy==1.19.5
packaging==21.3
pluggy==1.0.0
py==1.11.0
pymongo==3.4.0
pyparsing==3.0.8
pyquery==1.4.3
pytest==7.0.1
python-dateutil==2.8.2
requests==2.27.1
ruia==0.8.4
ruia-ua==0.0.2
sanic==0.5.1
sanic-session==0.1.2
schedule==1.1.0
sentry-sdk==1.5.10
six==1.16.0
soupsieve==2.3.2.post1
tomli==1.2.3
typing-extensions==4.1.1
ujson==4.3.0
urllib3==1.26.9
uvloop==0.14.0
webencodings==0.5.1
websockets==9.1
yarl==1.7.2
zipp==3.6.0

11
soulbook/__init__.py Normal file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env python
"""
Created by howie.hu at 17-9-22.
"""
from sys import path as path_sys
from os import path as path_os
# from multiprocessing.managers import BaseManager
# from multiprocessing import freeze_support
# environment variable
path_sys.append(path_os.dirname(__file__))

View File

@ -0,0 +1,43 @@
#!/usr/bin/env python
import os
import logging
from .rules import *
logging_format = "[%(asctime)s] %(process)d-%(levelname)s "
logging_format += "%(module)s::%(funcName)s():l%(lineno)d: "
logging_format += "%(message)s"
logging.basicConfig(
format=logging_format,
level=logging.DEBUG
)
LOGGER = logging.getLogger()
def load_config():
"""
Load a config class
"""
os.environ['MODE'] = 'PRO'
mode = os.environ.get('MODE', 'DEV')
LOGGER.info('soulbook 启动模式:{}'.format(mode))
try:
# if mode == 'PRO':
# from .pro_config import ProConfig
# return ProConfig
# elif mode == 'DEV':
# from .dev_config import DevConfig
# return DevConfig
# else:
# from .dev_config import DevConfig
# return DevConfig
from .dev_config import DevConfig
return DevConfig
except ImportError:
from .config import Config
return Config
CONFIG = load_config()

40
soulbook/config/config.py Normal file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
import os
class Config():
"""
Basic config for soulbook
"""
# Application config
DEBUG = True
VAL_HOST = os.getenv('VAL_HOST', 'true')
FORBIDDEN = ['139.199.198.228']
HOST = ['127.0.0.1:8001', '0.0.0.0:8001', '127.0.0.1:8002', '0.0.0.0:8002']
TIMEZONE = 'Asia/Shanghai'
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36'
WEBSITE = dict(
IS_RUNNING=True,
TOKEN='',
AUTHOR_LATEST_COUNT=5,
)
SCHEDULED_DICT = dict(
SPIDER_INTERVAL=int(os.getenv('SPIDER_INTERVAL', 120)),
NOVELS_INTERVAL=int(os.getenv('SPIDER_INTERVAL', 180)),
)
# Engine config
URL_PHONE = 'https://m.baidu.com/s'
URL_PC = 'http://www.baidu.com/s'
# BAIDU_RN = 15
BAIDU_RN = 15
SO_URL = "https://www.so.com/s"
BY_URL = "https://www.bing.com/search"
DUCKGO_URL = "https://duckduckgo.com/html"
REMOTE_SERVER = {
'proxy_server': 'http://0.0.0.0:8002/'
}

View File

@ -0,0 +1,41 @@
#!/usr/bin/env python
import os
from .config import Config
class DevConfig(Config):
"""
Dev config for soulbook
"""
VAL_HOST = os.getenv('VAL_HOST', 'false')
# Database config
REDIS_DICT = dict(
IS_CACHE=True,
REDIS_ENDPOINT=os.getenv('REDIS_ENDPOINT', "localhost"),
REDIS_PORT=int(os.getenv('REDIS_PORT', 6379)),
REDIS_PASSWORD=os.getenv('REDIS_PASSWORD', None),
REDIS_PORT=6379,
CACHE_DB=0,
SESSION_DB=1,
POOLSIZE=10,
)
MONGODB = dict(
MONGO_HOST=os.getenv('MONGO_HOST', "127.0.0.1"),
MONGO_PORT=int(os.getenv('MONGO_PORT', 27017)),
MONGO_USERNAME="",
MONGO_PASSWORD="",
DATABASE='soulbook',
)
# website
WEBSITE = dict(
IS_RUNNING=os.getenv('OWLLOOK_IS_RUNNING', True),
TOKEN=os.getenv('OWLLOOK_TOKEN', '')
)
AUTH = {
"Owllook-Api-Key": os.getenv('OWLLOOK_API_KEY', "your key")
}

View File

@ -0,0 +1,21 @@
# gunicorn config
# gunicorn -c config/gunicorn.py --worker-class sanic.worker.GunicornWorker server:app
import os
os.environ['MODE'] = 'PRO'
WORKERS = os.getenv('WORKERS', 2)
TIMEOUT = os.getenv('TIMEOUT', 60)
bind = '0.0.0.0:8001'
backlog = 2048
workers = WORKERS
worker_connections = 1000
keepalive = 2
spew = False
daemon = False
umask = 0
timeout = TIMEOUT
preload = True

672
soulbook/config/rules.py Normal file
View File

@ -0,0 +1,672 @@
#!/usr/bin/env python
from collections import namedtuple
####################################### 规则 ###########################################
# DOMAIN
BLACK_DOMAIN = ['www.17k.com', 'mm.17k.com', 'www.xs8.cn', 'www.zongheng.com', 'yunqi.qq.com', 'chuangshi.qq.com',
'book.qidian.com', 'www.soduso.com', 'pages.book.qq.com', 'book.km.com', 'www.lread.net',
'www.0dsw.com', 'www.5200xsb.com', 'www.80txt.com', 'www.sodu.tw', 'www.shuquge.com',
'www.shenmanhua.com', 'xiaoshuo.sogou.com', 'www.999wx.com', 'zetianji8.com', 'www.bookso.net',
'm.23us.com', 'www.qbxsw.com', 'www.zhuzhudao.com', 'www.shengyan.org', 'www.360doc.com',
'www.ishuo.cn', 'read.qidian.com', 'www.yunlaige.com', 'www.qidian.com', 'www.sodu888.com',
'www.siluke.cc', 'read.10086.cn', 'www.pbtxt.com', 'c4txt.com', 'www.bokon.net', 'www.sikushu.net',
'www.is028.cn', 'www.tadu.com', 'www.kudu8.com', 'www.bmwen.com', 'www.5858xs.com', 'www.yiwan.com',
'www.x81zw.com', 'www.123du.cc', 'www.chashu.cc', '20xs.com', 'www.haxwx.net', 'www.dushiwenxue.com',
"www.yxdown.com", 'www.jingcaiyuedu.com', 'www.zhetian.org', 'www.xiaoshuo02.com', 'www.xiaoshuo77.com',
'www.868xh.com', 'dp.changyou.com', 'www.iyouman.com', 'www.qq717.com', 'www.yznn.com', "www.69w.cc",
"www.doupocangqiong1.com", "www.manhuatai.com", "www.5wxs.com", "www.ggshuji.com", "www.msxf.net",
"www.mianhuatang.la", "www.boluoxs.com", "www.lbiquge.top", "www.69shu.com", "www.qingkan520.com",
"book.douban.com", "movie.douban.com", "www.txshuku.com", "lz.book.sohu.com", "www.3gsc.com.cn",
"www.txtshu365.com", "www.517yuedu.com", "www.baike.com", "read.jd.com", "www.zhihu.com", "wshuyi.com",
"www.19lou.tw", "www.chenwangbook.com", "www.aqtxt.com", "book.114la.com", "www.niepo.net",
"me.qidian.com", "www.gengd.com", "www.77l.com", "www.geilwx.com", "www.97xiao.com", "www.anqu.com",
"www.wuxiaxs.com", "yuedu.163.com", "b.faloo.com", "bbs.qidian.com", "jingji.qidian.com", "www.sodu.cc",
"forum.qdmm.com", "www.qdmm.com", "game.91.com", "www.11773.com", "mt.sohu.com", "book.dajianet.com",
"haokan.17k.com", "www.qmdsj.com", "www.jjwxc.net", "ishare.iask.sina.com.cn", "www.cmread.com",
"www.52ranwen.net", "www.dingdianzw.com", "www.topber.com", "www.391k.com", "www.qqxzb.com",
"www.zojpw.com", "www.pp8.com", "www.bxwx.org", "www.hrsxb.com", "www.497.com", "www.d8qu.com",
"www.duwanjuan.com", "www.05935.com", "book.zongheng.com", "www.55x.cn", "www.freexs.cn",
"xiaoshuo.360.cn", "www.3kw.cc", "www.gzbpi.com", "book.sina.com.cn", "www.vodtw.com", "wenda.so.com",
"product.dangdang.com", "www.chuiyao.com", "novel.slieny.com", "www.bilibili.com", "donghua.dmzj.com",
"www.yaojingweiba.com", "www.qb5200.com", "www.520tingshu.com", "www.567zw.com", "www.zjrxz.com",
"v.qq.com", "blog.sina.com.cn", "www.hackhome.com", "news.fznews.com.cn", "www.jingyu.com",
"news.so.com", "www.sodu3.com", "vipreader.qidian.com", "www.mozhua9.com", "www.iqiyi.com",
"xs.sogou.com"]
# 针对某些网站检索出来的地址和真正的目录地址不一样从而进行替换
REPLACE_RULES = {
"www.miaobige.com": {
'old': 'miaobige.com/book/',
'new': 'miaobige.com/read/'
},
"www.5ccc.net": {
'old': '5ccc.net/wksz_info/',
'new': '5ccc.net/xiaoshuo/'
},
"www.7kankan.com": {
'old': '7kankan.com/files/article/info/',
'new': '7kankan.com/files/article/html/'
},
"www.xqingdou.net": {
'old': 'xqingdou.net/book_',
'new': 'xqingdou.net/chapter_'
},
"www.wuyanxia.net": {
'old': 'wuyanxia.net/book/',
'new': 'wuyanxia.net/read/'
},
"www.263zw.com": {
'old': '263zw.com/402770/',
'new': '263zw.com/402770/list/'
},
}
# 搜索引擎检索优先级
ENGINE_PRIORITY = ['bing', '360', 'baidu', 'bing', 'duck_go']
# ENGINE_PRIORITY = ['baidu', '360', 'bing', 'duck_go']
# Rules
Rules = namedtuple('Rules', 'content_url chapter_selector content_selector')
LatestRules = namedtuple('LatestRules', 'plan meta_value selector')
# 获取小说最新章节
PLAN_01 = LatestRules(
True,
{'latest_chapter_name': 'og:novel:latest_chapter_name', 'latest_chapter_url': 'og:novel:latest_chapter_url'},
None,
)
LATEST_RULES = {
"www.biqugex.com": PLAN_01,
"www.x23us.com": PLAN_01,
"www.23us.la": PLAN_01,
"www.sqsxs.com": PLAN_01,
"www.nuomi9.com": PLAN_01,
"www.biquge.info": PLAN_01,
"www.biquge.tw": PLAN_01,
"www.qu.la": PLAN_01,
"www.ybdu.com": PLAN_01,
"www.wenxuemi.com": PLAN_01,
"www.biquge.com": PLAN_01,
"www.23us.cc": PLAN_01,
"www.xs222.com": PLAN_01,
"www.lewen8.com": PLAN_01,
"www.bqg5200.com": PLAN_01,
"www.vodtw.com": PLAN_01,
"www.6mao.com": PLAN_01,
"www.biquge.sh": PLAN_01,
"www.touxiang.la": PLAN_01,
"www.bxquge.com": PLAN_01,
"www.beidouxin.com": PLAN_01,
"www.biquge.lu": PLAN_01,
"www.263zw.com": PLAN_01,
"www.3qzone.com": PLAN_01,
"wwww.yooread.com": PLAN_01,
# "www.suimeng.la": PLAN_01,
"www.bequge.com": PLAN_01,
"www.biquku.co": PLAN_01,
"www.xbqge.com": PLAN_01,
"www.aiquxs.com": PLAN_01,
"www.23us.com": PLAN_01,
"www.biqiuge.com": PLAN_01,
"www.ddbiquge.com": PLAN_01,
"www.abocms.cn": PLAN_01,
"www.a306.com": PLAN_01,
"www.liewen.cc": PLAN_01,
"www.8535.org": PLAN_01,
"www.dingdianzw.com": PLAN_01,
"www.biquge.cc": PLAN_01,
"www.111bz.org": PLAN_01,
"www.biqugebook.com": PLAN_01,
"www.e8zw.com": PLAN_01,
"www.xqqxs.com": PLAN_01,
"tianyibook.la": PLAN_01,
"www.lingdianksw.com": PLAN_01,
"www.qb5.tw": PLAN_01,
"www.quanben.com": PLAN_01,
"www.58xs.com": PLAN_01,
"www.biqukan.com": PLAN_01,
"www.yssm.org": PLAN_01,
"www.81zw.com": PLAN_01,
"www.ymoxuan.com": PLAN_01,
"www.mytxt.cc": PLAN_01,
"www.woquge.com": PLAN_01,
"www.biquguo.com": PLAN_01,
"www.8jzw.cc": PLAN_01,
"www.biquge.tv": PLAN_01,
"www.biquge5200.com": PLAN_01,
"www.8jzw.com": PLAN_01,
"www.23xsw.cc": PLAN_01,
"www.miaobige.com": PLAN_01,
"www.xs.la": PLAN_01,
"www.44pq.co": PLAN_01,
"www.50zw.la": PLAN_01,
"www.33xs.com": PLAN_01,
"www.zwdu.com": PLAN_01,
"www.ttzw.com": PLAN_01,
"www.zanghaihuatxt.com": PLAN_01,
"www.kuxiaoshuo.com": PLAN_01,
"www.biqudu.com": PLAN_01,
"www.biqugeg.com": PLAN_01,
"www.23txt.com": PLAN_01,
"www.baquge.tw": PLAN_01,
"www.23qb.com": PLAN_01,
"www.lread.cc": PLAN_01,
"www.biqudao.com": PLAN_01,
"www.laidudu.com": PLAN_01,
"www.kxs7.com": PLAN_01,
"www.biquguan.com": PLAN_01,
"www.biquta.com": PLAN_01,
"www.xs98.com": PLAN_01,
"www.bqge.org": PLAN_01,
"www.58xs.tw": PLAN_01,
"www.187ks.com": PLAN_01,
"www.yikanxiaoshuo.com": PLAN_01,
"www.23zw.me": PLAN_01,
"www.37zw.net": PLAN_01,
"www.biquge.cm": PLAN_01,
"www.kanshu58.com": PLAN_01,
"www.biqumo.com": PLAN_01,
"www.mpxiaoshuo.com": PLAN_01,
"www.23wx.cm": PLAN_01,
"www.biquge.jp": PLAN_01,
"www.biqugexsw.com": PLAN_01,
"www.biqu6.com": PLAN_01,
"www.xiuxs.com": PLAN_01,
"www.booktxt.net": PLAN_01,
"www.biqule.com": PLAN_01,
"www.biquzi.com": PLAN_01,
"www.biquku.la": PLAN_01,
"www.00ksw.org": PLAN_01,
"www.bqg.cc": PLAN_01,
"www.biqugezw.com": PLAN_01,
"www.bbiquge.com": PLAN_01,
"www.aikantxt.la": PLAN_01,
"www.biquge.com.tw": PLAN_01,
"www.xxbiquge.com": PLAN_01,
"www.biquwo.com": PLAN_01,
"www.ixs.cc": PLAN_01,
# 其他规则
# "www.50331.net": LatestRules(
# False,
# None,
# {'content_url': "http://www.50331.net/", 'tag': 'span.zzjie a'}
# )
}
RULES = {
# demo 'name': Rules('content_url', {chapter_selector}, {content_selector})
# content_url=1 表示章节链接使用本身自带的链接,不用拼接
# content_url=0 表示章节网页需要当前页面url拼接
# 'www.biqule.com': Rules('www.biqule.com', {'class': 'box_con'},{}),
# 'www.lingdiankanshu.com': Rules('www.lingdiankanshu.com', {'class': 'box_con'}, {}),
# 'www.hhlwx.com': Rules('www.hhlwx.co', {'class': 'chapterlist'},{}),
'www.biquwu.cc': Rules('https://www.biquwu.cc/', {'class': 'box_con'}, {'id': 'content'}),
'www.quyuege.com': Rules('0', {'class': 'mod-article-list'}, {'class': 'page-content'}),
# 已解析
'www.biqugex.com': Rules('http://www.biqugex.com/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.bbiquge.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquge.info': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.37zw.net': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquku.la': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquge.sh': Rules('1', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquge.co': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.00ksw.org': Rules('0', {'class': 'ml_list'}, {'id': 'articlecontent'}),
# 已解析
'www.bqge.org': Rules('http://www.bqge.org/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.aikantxt.la': Rules('http://www.aikantxt.la/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquzi.com': Rules('http://www.biquzi.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.bqg.cc': Rules('http://www.bqg.cc/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquge.jp': Rules('0', {'id': 'list'}, {'id': 'content'}),
# 已解析
'www.vipzw.com': Rules('http://www.vipzw.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquge5200.com': Rules('1', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.zanghaihuatxt.com': Rules('http://www.zanghaihuatxt.com/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.xiuxs.com': Rules('http://www.xiuxs.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.1biquge.com': Rules('http://www.1biquge.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.xiaoshuowan.com': Rules('http://www.xiaoshuowan.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqugela.com': Rules('http://www.biqugela.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqu6.com': Rules('http://www.biqu6.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.zhuaji.org': Rules('0', {'tag': 'dd'}, {'id': 'content'}),
# 已解析
'www.sqsxs.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquge.tv': Rules('http://www.biquge.tv/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquta.com': Rules('https://www.biquta.com/', {'class': 'box_con'}, {'id': 'content'}),
# # 已解析
'www.xbiquge.la': Rules('http://www.xbiquge.la/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquge.cm': Rules('http://www.biquge.cm/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.23qb.com': Rules('https://www.23qb.com/', {'id': 'chapterList'}, {'id': 'TextContent'}),
# 已解析
# 'www.txtwan.com': Rules('http://www.txtwan.com/', {'id': 'chapterList'}, {'id': 'txt'}),
# 已解析
'www.biqugexsw.com': Rules('http://www.biqugexsw.com/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.kuxiaoshuo.com': Rules('1', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.laidudu.com': Rules('http://www.laidudu.com/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.kanshu58.com': Rules('0', {'class': 'chapters'}, {'id': 'content'}),
# 已解析
'www.mpxiaoshuo.com': Rules('0', {'class': 'mulu_list'}, {'id': 'htmlContent'}),
# 已解析
'www.23zw.me': Rules('0', {'id': 'chapter_list'}, {'id': 'text_area'}),
# 已解析
'www.187ks.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.58xs.tw': Rules('http://www.58xs.tw/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquguan.com': Rules('http://www.biquguan.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.xs98.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.kxs7.com': Rules('http://www.kxs7.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqudao.com': Rules('https://www.biqudao.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.nuomi9.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'book.sfacg.com': Rules('http://book.sfacg.com/', {'class': 'story-catalog'}, {'tag': 'p'}),
# 已解析
'www.7kshu.com': Rules('0', {'id': 'chapterlist'}, {'id': 'content'}),
# 已解析
'www.lread.cc': Rules('http://www.lread.cc/', {'class': 'box_con'}, {'id': 'booktext'}),
# 已解析
'www.baquge.tw': Rules('http://www.baquge.tw/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqudu.com': Rules('https://www.biqudu.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqugeg.com': Rules('http://www.biqugeg.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.23txt.com': Rules('http://www.23txt.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.ttzw.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.zwdu.com': Rules('http://www.zwdu.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.33xs.com': Rules('http://www.33xs.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.50zw.la': Rules('0', {'class': 'chapterlist'}, {'id': 'htmlContent'}),
# 已解析
'www.44pq.co': Rules('0', {'class': 'chapterlist'}, {'id': 'BookText'}),
# 已解析
'www.wddsnxn.org': Rules('1', {'class': 'booklist'}, {'id': 'BookText'}),
# 已解析
'mianzhuan.wddsnxn.org': Rules('1', {'class': 'booklist'}, {'id': 'BookText'}),
# 已解析
'www.a306.com': Rules('http://www.a306.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.xs52.com': Rules('0', {'id': 'chapter_list'}, {'id': 'text_c'}),
# 已解析
'www.xs.la': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.23xsw.cc': Rules('http://www.23xsw.cc/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.8jzw.com': Rules('http://www.8jzw.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquguo.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.woquge.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.zhonghuawuxia.com': Rules('1', {'class': 'list'}, {'id': 'content'}),
# 已解析
'www.mytxt.cc': Rules('http://www.mytxt.cc/', {'class': 'story_list_m62topxs'}, {'class': 'detail_con_m62topxs'}),
# 已解析
'www.136txt.com': Rules('1', {'class': 'directory_con'}, {'id': 'chapterContent'}),
# 已解析
'www.xs74.com': Rules('1', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.yssm.org': Rules('0', {'class': 'chapterlist'}, {'id': 'content'}),
# 已解析
'www.luoxia.com': Rules('1', {'class': 'book-list'}, {'tag': 'p'}),
# 已解析
'www.sbkk88.com': Rules('http://www.sbkk88.com/', {'class': 'leftList'}, {'id': 'f_article'}),
# 已解析
'www.dxsxs.com': Rules('http://www.dxsxs.com/', {'id': 'yuedu'}, {'class': 'zw'}),
# 已解析
'www.wenku8.com': Rules('0', {'class': 'css'}, {'id': 'content'}),
# 已解析
'www.xqingdou.net': Rules('http://www.xqingdou.net/', {'class': 'dirconone'}, {'id': 'chapter_content'}),
# 已解析
'www.zuowe.com': Rules('http://www.zuowe.com/', {'class': 'book_list'}, {'id': 'htmlContent'}),
# 已解析
'www.biqugek.com': Rules('1', {'class': 'book_list'}, {'id': 'htmlContent'}),
# 已解析
'www.wuyanxia.net': Rules('http://www.wuyanxia.net/', {'class': 'zjlist4'}, {'id': 'htmlContent'}),
# 已解析
'www.50331.net': Rules('http://www.50331.net/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.wenxuemi.com': Rules('http://www.wenxuemi.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.xs222.com': Rules('http://www.xs222.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.lewen8.com': Rules('http://www.lewen8.com/', {'id': 'chapterlist'}, {'id': 'content'}),
# 已解析
'www.5ccc.net': Rules('0', {'class': 'acss'}, {'id': 'content'}),
# 已解析
# 'www.suimeng.la': Rules('0', {'class': 'acss'}, {'id': 'ccontent'}),
# 已解析
'www.bqg5200.com': Rules('http://www.bqg5200.com/', {'id': 'readerlist'}, {'id': 'content'}),
# 已解析
'www.vodtw.com': Rules('0', {'class': 'insert_list'}, {'class': 'contentbox'}),
# 已解析
'www.6mao.com': Rules('http://www.6mao.com/', {'class': 'liebiao_bottom'}, {'id': 'neirong'}),
# 已解析
'www.touxiang.la': Rules('http://www.touxiang.la/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.7kankan.com': Rules('0', {'class': 'uclist'}, {'id': 'content'}),
# 已解析
'www.biqugetw.com': Rules('http://www.biqugetw.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'gdbzkz.com': Rules('1', {'class': 'mulu'}, {'class': 'content-body'}),
# 已解析
'www.gdbzkz.com': Rules('1', {'class': 'mulu'}, {'class': 'content-body'}),
# 已解析
'www.freexs.cn': Rules('0', {'class': 'readout'}, {'class': 'shuneirong'}),
# 已解析
'www.bxquge.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.beidouxin.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.3qzone.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.97xs.net': Rules('1', {'class': 'box'}, {'id': 'htmlContent'}),
# 已解析
'www.7dsw.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.263zw.com': Rules('1', {'class': 'chapter'}, {'id': 'chapterContent'}),
# 已解析
'www.biquge5.com': Rules('1', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.yooread.com': Rules('http://www.yooread.com', {'id': 'chapterList'}, {'tag': 'p'}),
# 已解析
'www.xs82.com': Rules('0', {'class': 'chapterlist'}, {'id': 'content'}),
# 已解析
'www.kanshuhai.com': Rules('0', {'id': 'book'}, {'id': 'content'}),
# 已解析
'www.bequge.com': Rules('https://www.bequge.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析 请求失败
# 'www.biquge5200.com': Rules('1', {'id': 'list'}, {'id': 'content'}),
# 已解析
'www.biquku.co': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.xbqge.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.aiquxs.com': Rules('0', {'id': 'list'}, {'id': 'booktext'}),
# 已解析
# 'www.piaotian.com': Rules('0', {'class': 'centent'}, {'class': 'fonts_mesne'}),
# 已解析
'www.ttshu.com': Rules('http://www.ttshu.com', {'class': 'border'}, {'id': 'content'}),
# 已解析
'www.23us.com': Rules('0', {'id': 'at'}, {'id': 'contents'}),
# 已解析
'www.x23us.com': Rules('0', {'id': 'at'}, {'id': 'contents'}),
# 已解析
'www.23wx.cc': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.23wx.cm': Rules('0', {'class': 'book_list'}, {'id': 'htmlContent'}),
# 已解析
'www.ddbiquge.com': Rules('http://www.ddbiquge.com', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.abocms.cn': Rules('http://www.abocms.cn/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.liewen.cc': Rules('https://www.liewen.cc/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.heiyange.com': Rules('http://www.heiyange.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.8535.org': Rules('0', {'class': 'booklist'}, {'class': 'txtc'}),
# 已解析
'www.dingdianzw.com': Rules('http://www.dingdianzw.com/', {'id': 'bgdiv'}, {'id': 'content'}),
# 已解析
'www.biquge.cc': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.lewenxiaoshuo.com': Rules('1', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.111bz.org': Rules('http://www.111bz.org/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqugebook.com': Rules('http://www.biqugebook.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.e8zw.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.xqqxs.com': Rules('0', {'class': 'box_con'}, {'class': 'content'}),
# 已解析
'www.139book.com': Rules('http://www.139book.com/', {'class': 'list_box'}, {'class': 'box_box'}),
# 已解析
'www.jcdf99.com': Rules('0', {'class': 'list_box'}, {'id': 'content'}),
# 已解析
'www.tianzeba.com': Rules('http://www.tianzeba.com/', {'class': 'chapterlist'}, {'id': 'BookText'}),
# 已解析
'www.kanshuwangzhan.com': Rules('0', {'id': 'chapterlist'}, {'id': 'booktext'}),
# 已解析
'tianyibook.la': Rules('http://tianyibook.la/', {'class': 'chapterlist'}, {'id': 'BookText'}),
# 已解析
'www.quanben.net': Rules('http://www.quanben.net/', {'class': 'chapterlist'}, {'id': 'BookText'}),
# 已解析
# 'www.zhetian.org': Rules('http://www.zhetian.org', {'class': 'body '}, {'class': 'content'}),
# 已解析
'www.lingdianksw.com': Rules('0', {'class': 'acss'}, {'id': 'ccontent'}),
# 已解析
'www.qb5.tw': Rules('http://www.qb5.tw/', {'class': 'zjbox'}, {'id': 'content'}),
# 已解析
'www.ybdu.com': Rules('0', {'class': 'mulu_list'}, {'id': 'htmlContent'}),
# 已解析
'www.quanben.com': Rules('0', {'class': 'mulu_list'}, {'id': 'htmlContent'}),
# 已解析
'www.fhxs.com': Rules('1', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquge.biz': Rules('http://www.biquge.biz/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.58xs.com': Rules('http://www.58xs.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqukan.com': Rules('http://www.biqukan.com/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.shuyuelou.com': Rules('http://www.shuyuelou.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.mangg.com': Rules('http://www.mangg.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.50zw.com': Rules('0', {'class': 'chapterlist'}, {'id': 'htmlContent'}),
# 已解析
'www.lingdiankanshu.co': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqiku.com': Rules('http://www.biqiku.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.duilianku.com': Rules('http://www.duilianku.com/', {'id': 'list'}, {'class': 'chapter'}),
# 已解析
'www.5xiaxiaoshuo.com': Rules('http://www.5xiaxiaoshuo.com/', {'class': 'art_listmain_main'}, {'id': 'content'}),
# 已解析
'www.81xsw.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.wxguan.com': Rules('http://www.wxguan.com/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.qb5200.tw': Rules('http://www.qb5200.tw/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.fox2008.cn': Rules('http://www.fox2008.cn/', {'class': 'book'}, {'id': 'chapterContent'}),
# 已解析
'www.22zw.com': Rules('0', {'class': 'acss'}, {'id': 'content'}),
# 已解析
'www.k6uk.com': Rules('0', {'class': 'acss'}, {'id': 'content'}),
# 已解析
'www.126shu.com': Rules('http://www.126shu.com/', {'id': 'list'}, {'id': 'content'}),
# 已解析
'www.kooxs.com': Rules('0', {'class': 'list'}, {'id': 'content'}),
# 已解析
'www.shubaotxt.com': Rules('0', {'class': 'list'}, {'id': 'content'}),
# 已解析
'www.muyuge.com': Rules('1', {'id': 'xslist'}, {'id': 'content'}),
# 已解析
# 'www.daizhuzai.com': Rules('http://www.daizhuzai.com', {'class': 'dirlist'}, {'class': 'content'}),
# 已解析
'www.biqu.la': Rules('0', {'class': 'book_list'}, {'id': 'htmlContent'}),
# 已解析
'shushu.com.cn': Rules('http://shushu.com.cn/', {'id': 'dirsort01'}, {'id': 'content'}),
# 已解析
'www.shuhai.com': Rules('0', {'class': 'box_chap'}, {'id': 'readcon'}),
# 已解析
'www.37yue.com': Rules('0', {'class': 'list-chapter'}, {'class': 'chapter'}),
# 已解析
'www.35zw.com': Rules('0', {'class': 'book_list'}, {'id': 'htmlContent'}),
# 已解析
'www.xinshu.in': Rules('http://www.xinshu.in/', {'class': 'list_box'}, {'class': 'box_box'}),
# 已解析
'www.lwxs520.com': Rules('0', {'class': 'dccss'}, {'id': 'content'}),
# 已解析
'www.lwxs.la': Rules('http://www.lwxs.la/', {'id': 'defaulthtml4'}, {'id': 'content'}),
# 已解析
'www.biqule.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.33yq.com': Rules('1', {'class': 'box_con'}, {'class': 'zhangjieTXT'}),
# 已解析
'www.dishuge.com': Rules('1', {'class': 'update'}, {'tag': 'p'}),
# 已解析
'www.qu.la': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.shuge.net': Rules('http://www.shuge.ne/t', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.daomengren.com': Rules('http://www.daomengren.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.81zw.net': Rules('http://www.81zw.net/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.09xs.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.fhxiaoshuo.com': Rules('1', {'class': 'box_con'}, {'class': 'zhangjieTXT'}),
# 已解析
'www.yikanxiaoshuo.com': Rules('http://www.yikanxiaoshuo.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.1xiaoshuo.com': Rules('http://www.1xiaoshuo.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.kanshu.la': Rules('http://www.kanshu.la/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.kbiquge.com': Rules('http://www.kbiquge.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.00ksw.net': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.booktxt.net': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'wanmeishijiexiaoshuo.org': Rules('1', {'class': 'bg'}, {'class': 'content'}),
# 已解析
'www.sosoxiaoshuo.cc': Rules('http://www.sosoxiaoshuo.cc/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.ciluke.com': Rules('0', {'id': 'list'}, {'id': 'content'}),
# 已解析
'www.81zw.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.cilook.net': Rules('0', {'id': 'cl_content'}, {'id': 'content'}),
# 已解析
'www.baoliny.com': Rules('http://www.baoliny.com/', {'class': 'readerListShow'}, {'id': 'content'}),
# 已解析
'www.biquge.tw': Rules('http://www.biquge.tw/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.7788xs.net': Rules('http://www.7788xs.net/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.06sy.com': Rules('http://www.06sy.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqumo.com': Rules('https://www.biqumo.com/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.kanshuzhe.com': Rules('http://www.kanshuzhe.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biqiuge.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.lwxs.com': Rules('0', {'class': 'box_con'}, {'id': 'TXT'}),
# 已解析
'www.biqugezw.com': Rules('http://www.biqugezw.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析 经常跳到无法预料的网站 故禁止
# 'www.is028.cn': Rules('http://www.biquge.com.tw', {'class': 'box_con'}, {'id': 'content'}),
# www.is028.cn会跳转到http://www.biquge.com.tw
'www.biquge.com.tw': Rules('http://www.biquge.com.tw/', {'class': 'box_con'}, {'id': 'content'}),
# 'www.xs82.com': Rules('-1', {'class': 'chapterlist'}, {'id': 'content'}),
# 已解析
'www.shuqizw.com': Rules('http://www.shuqizw.com/', {'class': 'article_texttitleb'}, {'id': 'book_text'}),
# 已解析
'read.ixdzs.com': Rules('0', {'class': 'catalog'}, {'class': 'content'}),
# 已解析
'www.shumilou.net': Rules('0', {'class': 'chapterlist'}, {'id': 'BookText'}),
# 已解析
'www.8shuw.com': Rules('1', {'class': 'chapterlist'}, {'id': 'readtext'}),
# 已解析
# 'www.ttshu.com': Rules('http://www.ttshu.com', {'class': 'border'}, {'id': 'content'}),
# 已解析
'www.heiyan.la': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.bbsa5.com': Rules('1', {'class': 'panel'}, {'class': 'content-body'}),
# 已解析
'www.tycqxs.com': Rules('http://www.tycqxs.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.miaobige.com': Rules('https://www.miaobige.com/', {'id': 'readerlists'}, {'id': 'content'}),
# 已解析
'www.dashubao.net': Rules('0', {'class': 'ml_main'}, {'class': 'yd_text2'}),
# 已解析
'www.23zw.com': Rules('0', {'id': 'chapter_list'}, {'id': 'text_area'}),
# 已解析
'www.23us.la': Rules('http://www.23us.la/', {'class': 'inner'}, {'id': 'content'}),
# 已解析
'www.2952.cc': Rules('0', {'class': 'inner'}, {'id': 'content'}),
# 已解析
'www.23us.cc': Rules('0', {'class': 'inner'}, {'id': 'content'}),
# 已解析
'www.13xs.com': Rules('0', {'class': 'box_con'}, {'id': 'booktext'}),
# 已解析
'www.tsxsw.com': Rules('0', {'class': 'bdsub'}, {'id': 'contents'}),
# 已解析
'www.ymoxuan.com': Rules('1', {'class': 'mulu'}, {'id': 'content'}),
'www.ixs.cc': Rules('https:', {'class': 'mulu'}, {'id': 'content'}),
# 已解析
'zetianjiba.net': Rules('1', {'class': 'bg'}, {'class': 'content'}),
# 已解析
'www.37zw.com': Rules('0', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.555zw.com': Rules('0', {'class': 'dir'}, {'id': 'content'}),
# 已解析
'www.jueshitangmen.info': Rules('1', {'class': 'bg'}, {'class': 'content'}),
# 已解析
'www.bxwx9.org': Rules('0', {'class': 'TabCss'}, {'id': 'content'}),
# 已解析
'www.xxbiquge.com': Rules('https://www.xxbiquge.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.biquwo.com': Rules('https://www.biquwo.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.fs23.com': Rules('http://www.fs23.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.longtengx.com': Rules('http://www.longtengx.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.lingyu.org': Rules('http://www.lingyu.org/', {'class': 'mt10'}, {'id': 'htmlContent'}),
# 已解析
'www.aszw8.com': Rules('0', {'id': 'at'}, {'id': 'contents'}),
# 已解析
'www.23us.so': Rules('1', {'id': 'at'}, {'id': 'contents'}),
# 已解析
'www.biquge.lu': Rules('http://www.biquge.lu/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.3zm.net': Rules('http://www.3zm.net/', {'class': 'listmain'}, {'id': 'content'}),
# 已解析
'www.biquge.com': Rules('http://www.biquge.com/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
'www.kanshuzhong.com': Rules('0', {'class': 'bookcontent'}, {'class': 'textcontent'}),
# 已解析
'www.siluke.tw': Rules('http://www.siluke.tw/', {'class': 'box_con'}, {'id': 'content'}),
# 已解析
# 'www.ttshu.com': Rules('http://www.ttshu.com', {'class': 'border'}, {'id': 'content'}),
}

View File

@ -0,0 +1,899 @@
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)
Mozilla/4.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)
Mozilla/1.22 (compatible; MSIE 10.0; Windows 3.1)
Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))
Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 4.0; InfoPath.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 4.0; Tablet PC 2.0; InfoPath.3; .NET4.0C; .NET4.0E)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; chromeframe/11.0.696.57)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) chromeframe/10.0.648.205
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; chromeframe/11.0.696.57)
Mozilla/5.0 ( ; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 7.1; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; AskTB5.5)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.2; .NET4.0C; .NET4.0E)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C)
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; FDM; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; Tablet PC 2.0)
Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)
Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322)
Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727)
Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.0; Trident/4.0; InfoPath.1; SV1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 3.0.04506.30)
Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.0; Trident/4.0; FBSMTWB; .NET CLR 2.0.34861; .NET CLR 3.0.3746.3218; .NET CLR 3.5.33652; msn OptimizedIE8;ENUS)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; Media Center PC 6.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.3; .NET4.0C; .NET4.0E; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MS-RTC LM 8)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 3.0)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; msn OptimizedIE8;ZHCN)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; InfoPath.3; .NET4.0C; .NET4.0E) chromeframe/8.0.552.224
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; .NET4.0C; .NET4.0E; Zune 4.7; InfoPath.3)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; .NET4.0C; .NET4.0E; Zune 4.7)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; Zune 4.0)
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MS-RTC LM 8; Zune 4.7)
Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20110324 Firefox/4.2a1pre
Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20100101 Firefox/4.2a1pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.2a1pre) Gecko/20110324 Firefox/4.2a1pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.2a1pre) Gecko/20110323 Firefox/4.2a1pre
Mozilla/5.0 (X11; Linux x86_64; rv:2.0b9pre) Gecko/20110111 Firefox/4.0b9pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b9pre) Gecko/20101228 Firefox/4.0b9pre
Mozilla/5.0 (Windows NT 5.1; rv:2.0b9pre) Gecko/20110105 Firefox/4.0b9pre
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b8pre) Gecko/20101114 Firefox/4.0b8pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101213 Firefox/4.0b8pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101128 Firefox/4.0b8pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101114 Firefox/4.0b8pre
Mozilla/5.0 (Windows NT 5.1; rv:2.0b8pre) Gecko/20101127 Firefox/4.0b8pre
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b8) Gecko/20100101 Firefox/4.0b8
Mozilla/5.0 (Windows NT 6.1; rv:2.0b7pre) Gecko/20100921 Firefox/4.0b7pre
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b7) Gecko/20101111 Firefox/4.0b7
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b7) Gecko/20100101 Firefox/4.0b7
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre
Mozilla/5.0 (Windows NT 6.1; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre Firefox/4.0b6pre
Mozilla/5.0 (X11; Linux x86_64; rv:2.0b4) Gecko/20100818 Firefox/4.0b4
Mozilla/5.0 (X11; Linux i686; rv:2.0b3pre) Gecko/20100731 Firefox/4.0b3pre
Mozilla/5.0 (Windows NT 5.2; rv:2.0b13pre) Gecko/20110304 Firefox/4.0b13pre
Mozilla/5.0 (Windows NT 5.1; rv:2.0b13pre) Gecko/20110223 Firefox/4.0b13pre
Mozilla/5.0 (X11; Linux i686; rv:2.0b12pre) Gecko/20110204 Firefox/4.0b12pre
Mozilla/5.0 (X11; Linux i686; rv:2.0b12pre) Gecko/20100101 Firefox/4.0b12pre
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b11pre) Gecko/20110128 Firefox/4.0b11pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110131 Firefox/4.0b11pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110129 Firefox/4.0b11pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110128 Firefox/4.0b11pre
Mozilla/5.0 (Windows NT 6.1; rv:2.0b11pre) Gecko/20110126 Firefox/4.0b11pre
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b11pre) Gecko/20110126 Firefox/4.0b11pre
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b10pre) Gecko/20110118 Firefox/4.0b10pre
Mozilla/5.0 (Windows NT 6.1; rv:2.0b10pre) Gecko/20110113 Firefox/4.0b10pre
Mozilla/5.0 (X11; Linux i686; rv:2.0b10) Gecko/20100101 Firefox/4.0b10
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:2.0b10) Gecko/20110126 Firefox/4.0b10
Mozilla/5.0 (Windows NT 6.1; rv:2.0b10) Gecko/20110126 Firefox/4.0b10
Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:2.0) Gecko/20110307 Firefox/4.0
Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:2.0) Gecko/20110404 Fedora/16-dev Firefox/4.0
Mozilla/5.0 (X11; Arch Linux i686; rv:2.0) Gecko/20110321 Firefox/4.0
Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows NT 6.1; rv:2.0) Gecko/20110319 Firefox/4.0
Mozilla/5.0 (Windows NT 6.1; rv:1.9) Gecko/20100101 Firefox/4.0
Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8
Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8
Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8
Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.3a5pre) Gecko/20100526 Firefox/3.7a5pre
Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5
Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20091218 Firefox 3.6b5
Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2b4) Gecko/20091124 Firefox/3.6b4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2b4) Gecko/20091124 Firefox/3.6b4
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2a1pre) Gecko/20090428 Firefox/3.6a1pre
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2a1pre) Gecko/20090405 Firefox/3.6a1pre
Mozilla/5.0 (X11; U; Linux i686; ru-RU; rv:1.9.2a1pre) Gecko/20090405 Ubuntu/9.04 (jaunty) Firefox/3.6a1pre
Mozilla/5.0 (Windows; Windows NT 5.1; es-ES; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre
Mozilla/5.0 (Windows; Windows NT 5.1; en-US; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre
Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20100915 Gentoo Firefox/3.6.9
Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.2.9) Gecko/20100913 Firefox/3.6.9
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9 ( .NET CLR 3.5.30729; .NET CLR 4.0.20506)
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-GB; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9
Mozilla/5.0 (X11; U; OpenBSD i386; en-US; rv:1.9.2.8) Gecko/20101230 Firefox/3.6.8
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100804 Gentoo Firefox/3.6.8
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100723 SUSE/3.6.8-0.1.1 Firefox/3.6.8
Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.2.8) Gecko/20100722 Ubuntu/10.04 (lucid) Firefox/3.6.8
Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8
Mozilla/5.0 (X11; U; Linux i686; fi-FI; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.8) Gecko/20100727 Firefox/3.6.8
Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.9.2.8) Gecko/20100725 Gentoo Firefox/3.6.8
Mozilla/5.0 (X11; U; FreeBSD i386; de-CH; rv:1.9.2.8) Gecko/20100729 Firefox/3.6.8
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-BR; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.8) Gecko/20100722 AskTbADAP/3.9.1.14019 Firefox/3.6.8
Mozilla/5.0 (Windows; U; Windows NT 6.1; he; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.8) Gecko/20100722 Firefox 3.6.8 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0C)
Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.8) Gecko/20100722 Firefox 3.6.8
Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.3) Gecko/20121221 Firefox/3.6.8
Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-TW; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0E
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100809 Fedora/3.6.7-1.fc14 Firefox/3.6.7
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100723 Fedora/3.6.7-1.fc13 Firefox/3.6.7
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.7) Gecko/20100726 CentOS/3.6-3.el5.centos Firefox/3.6.7
Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.7 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-PT; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 GTB7.1
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 GTB7.0
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6
Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-PT; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729; .NET4.0E)
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.4) Gecko/20100614 Ubuntu/10.04 (lucid) Firefox/3.6.4
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.4) Gecko/20100625 Gentoo Firefox/3.6.4
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-TW; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4
Mozilla/5.0 (Windows; U; Windows NT 6.1; ja; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; cs; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4
Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100527 Firefox/3.6.4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100527 Firefox/3.6.4
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-CA; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.0 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100503 Firefox/3.6.4 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; nb-NO; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3pre) Gecko/20100405 Firefox/3.6.3plugin1 ( .NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.2.3) Gecko/20100403 Fedora/3.6.3-4.fc13 Firefox/3.6.3
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100403 Firefox/3.6.3
Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.3) Gecko/20100401 SUSE/3.6.3-1.1 Firefox/3.6.3
Mozilla/5.0 (X11; U; Linux i686; ko-KR; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100404 Ubuntu/10.04 (lucid) Firefox/3.6.3
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.3
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3
Mozilla/5.0 (X11; U; Linux AMD64; en-US; rv:1.9.2.3) Gecko/20100403 Ubuntu/10.10 (maverick) Firefox/3.6.3
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.0 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; cs; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; ca; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2
Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 GTB7.0
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.2) Gecko/20100316 AskTbSPC2/3.9.1.14019 Firefox/3.6.2
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 GTB6 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 ( .NET CLR 3.0.04506.648)
Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 ( .NET CLR 3.0.04506.30)
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.7; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10pre) Gecko/20100902 Ubuntu/9.10 (karmic) Firefox/3.6.1pre
Mozilla/5.0 (X11; U; Linux x86_64; ja-JP; rv:1.9.2.16) Gecko/20110323 Ubuntu/10.10 (maverick) Firefox/3.6.16
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.16) Gecko/20110323 Ubuntu/9.10 (karmic) Firefox/3.6.16 FirePHP/0.5
Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16
Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16 ( .NET CLR 3.5.30729; .NET4.0E)
Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.9.1.13) Gecko/20100914 Firefox/3.6.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.16) Gecko/20110319 AskTbUTR/3.11.3.15590 Firefox/3.6.16
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.16pre) Gecko/20110304 Ubuntu/10.10 (maverick) Firefox/3.6.15pre
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 FirePHP/0.5
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.15) Gecko/20110330 CentOS/3.6-1.el5.centos Firefox/3.6.15
Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15 ( .NET CLR 3.5.30729; .NET4.0C) FirePHP/0.5
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.2.15) Gecko/20110303 AskTbBT4/3.11.3.15590 Firefox/3.6.15 ( .NET CLR 3.5.30729; .NET4.0C)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14pre) Gecko/20110105 Firefox/3.6.14pre
Mozilla/5.0 (X11; U; Linux armv7l; en-US; rv:1.9.2.14) Gecko/20110224 Firefox/3.6.14 MB860/Version.0.43.3.MB860.AmericaMovil.en.MX
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-AU; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14 GTB7.1 ( .NET CLR 3.5.30729)
Mozilla/5.0 Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; nb-NO; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.2.13) Gecko/20110103 Fedora/3.6.13-1.fc14 Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101223 Gentoo Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101219 Gentoo Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101206 Red Hat/3.6-3.el4 Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101206 Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; en-NZ; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; en-GB; rv:1.9.2.13) Gecko/20101206 Ubuntu/9.10 (karmic) Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; en-GB; rv:1.9.2.13) Gecko/20101206 Red Hat/3.6-2.el5 Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux x86_64; da-DK; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux MIPS32 1074Kf CPS QuadCore; en-US; rv:1.9.2.13) Gecko/20110103 Fedora/3.6.13-1.fc14 Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.2.13) Gecko/20101209 Fedora/3.6.13-1.fc13 Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.2.13) Gecko/20101206 Ubuntu/9.10 (karmic) Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.13) Gecko/20101209 CentOS/3.6-2.el5.centos Firefox/3.6.13
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13
Mozilla/5.0 (X11; U; NetBSD i386; en-US; rv:1.9.2.12) Gecko/20101030 Firefox/3.6.12
Mozilla/5.0 (X11; U; Linux x86_64; es-MX; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.04 (lucid) Firefox/3.6.12
Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.2.12) Gecko/20101027 Fedora/3.6.12-1.fc13 Firefox/3.6.12
Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.2.12) Gecko/20101026 SUSE/3.6.12-0.7.1 Firefox/3.6.12
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.12) Gecko/20101102 Gentoo Firefox/3.6.12
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.12) Gecko/20101102 Firefox/3.6.12
Mozilla/5.0 (X11; U; Linux ppc; fr; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.12
Mozilla/5.0 (X11; U; Linux i686; ko-KR; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.12
Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.12 GTB7.1
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.12) Gecko/20101027 Fedora/3.6.12-1.fc13 Firefox/3.6.12
Mozilla/5.0 (X11; FreeBSD x86_64; rv:2.0) Gecko/20100101 Firefox/3.6.12
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 ( .NET CLR 3.5.30729; .NET4.0E)
Mozilla/5.0 (Windows; U; Windows NT 6.0; sv-SE; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 (.NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; .NET CLR 3.5.21022)
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; de; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 GTB5
Mozilla/5.0 (X11; U; Linux x86_64; ru; rv:1.9.2.11) Gecko/20101028 CentOS/3.6-2.el5.centos Firefox/3.6.11
Mozilla/5.0 (X11; U; Linux armv7l; en-GB; rv:1.9.2.3pre) Gecko/20100723 Firefox/3.6.11
Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11
Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11 ( .NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux x86_64; pt-BR; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10 GTB7.1
Mozilla/5.0 (X11; U; Linux x86_64; el-GR; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10 GTB7.1
Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; es-AR; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10) Gecko/20100915 Ubuntu/9.04 (jaunty) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.2.11) Gecko/20101013 Ubuntu/10.10 (maverick) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; en-CA; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.10) Gecko/20100915 Ubuntu/9.10 (karmic) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.10) Gecko/20100914 SUSE/3.6.10-0.3.1 Firefox/3.6.10
Mozilla/5.0 (Windows; U; Windows NT 6.1; ro; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10
Mozilla/5.0 (Windows; U; Windows NT 6.1; nl; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.1) Gecko/20100122 firefox/3.6.1
Mozilla/5.0(Windows; U; Windows NT 7.0; rv:1.9.2) Gecko/20100101 Firefox/3.6
Mozilla/5.0(Windows; U; Windows NT 5.2; rv:1.9.2) Gecko/20100101 Firefox/3.6
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2) Gecko/20100222 Ubuntu/10.04 (lucid) Firefox/3.6
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2) Gecko/20100130 Gentoo Firefox/3.6
Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2) Gecko/20100308 Ubuntu/10.04 (lucid) Firefox/3.6
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.2pre) Gecko/20100312 Ubuntu/9.04 (jaunty) Firefox/3.6
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100128 Gentoo Firefox/3.6
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100115 Ubuntu/10.04 (lucid) Firefox/3.6
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 FirePHP/0.4
Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/3.6
Mozilla/5.0 (X11; FreeBSD i686) Firefox/3.6
Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU; rv:1.9.2) Gecko/20100105 MRA 5.6 (build 03278) Firefox/3.6 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; lt; rv:1.9.2) Gecko/20100115 Firefox/3.6
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a3pre) Gecko/20100306 Firefox3.6 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.8) Gecko/20100806 Firefox/3.6
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.3) Gecko/20100401 Firefox/3.6;MEGAUPLOAD 1.0
Mozilla/5.0 (Windows; U; Windows NT 6.1; ar; rv:1.9.2) Gecko/20100115 Firefox/3.6
Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2) Gecko/20100115 Firefox/3.6
Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2) Gecko/20100105 Firefox/3.6 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2) Gecko/20100115 Firefox/3.6 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b5pre) Gecko/20090517 Firefox/3.5b4pre (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b4pre) Gecko/20090409 Firefox/3.5b4pre
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b4pre) Gecko/20090401 Firefox/3.5b4pre
Mozilla/5.0 (X11; U; Linux i686; nl-NL; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 GTB5 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; fr; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 GTB5
Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.1.9) Gecko/20100402 Ubuntu/9.10 (karmic) Firefox/3.5.9 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.1.9) Gecko/20100330 Fedora/3.5.9-2.fc12 Firefox/3.5.9
Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1.1 Firefox/3.5.9 GTB7.0
Mozilla/5.0 (X11; U; Linux x86_64; es-CL; rv:1.9.1.9) Gecko/20100402 Ubuntu/9.10 (karmic) Firefox/3.5.9
Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1.1 Firefox/3.5.9
Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9
Mozilla/5.0 (X11; U; Linux i686; hu-HU; rv:1.9.1.9) Gecko/20100330 Fedora/3.5.9-1.fc12 Firefox/3.5.9
Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1 Firefox/3.5.9
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9 GTB7.1
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100315 Ubuntu/9.10 (karmic) Firefox/3.5.9
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.4) Gecko/20091028 Ubuntu/9.10 (karmic) Firefox/3.5.9
Mozilla/5.0 (Windows; U; Windows NT 6.1; tr; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9
Mozilla/5.0 (Windows; U; Windows NT 6.1; et; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9
Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; es-ES; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB5 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.5.9 (de)
Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB7.0 (.NET CLR 3.0.30618)
Mozilla/5.0 (X11; U; Linux x86_64; ru; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8
Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc11 Firefox/3.5.8
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100318 Gentoo Firefox/3.5.8
Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8
Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8
Mozilla/5.0 (X11; U; Linux i686; es-AR; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8
Mozilla/5.0 (X11; U; FreeBSD i386; ja-JP; rv:1.9.1.8) Gecko/20100305 Firefox/3.5.8
Mozilla/5.0 (Windows; U; Windows NT 6.1; sl; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729) FirePHP/0.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 GTB6
Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 GTB7.0 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2) Gecko/20100305 Gentoo Firefox/3.5.7
Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.7) Gecko/20091222 SUSE/3.5.7-1.1.1 Firefox/3.5.7
Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6
Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.2; fr; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.0.04506.648)
Mozilla/5.0 (Windows; U; Windows NT 5.1; fa; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 MRA 5.5 (build 02842) Firefox/3.5.7 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.6) Gecko/20100117 Gentoo Firefox/3.5.6
Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.6) Gecko/20091216 Fedora/3.5.6-1.fc11 Firefox/3.5.6 GTB6
Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.6) Gecko/20091201 SUSE/3.5.6-1.1.1 Firefox/3.5.6 GTB6
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.6) Gecko/20100118 Gentoo Firefox/3.5.6
Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6 GTB6
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6 GTB7.0
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091201 SUSE/3.5.6-1.1.1 Firefox/3.5.6
Mozilla/5.0 (X11; U; Linux i686; cs-CZ; rv:1.9.1.6) Gecko/20100107 Fedora/3.5.6-1.fc12 Firefox/3.5.6
Mozilla/5.0 (X11; U; Linux i686; ca; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; id; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.4 (build 02647) Firefox/3.5.6 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.5 (build 02842) Firefox/3.5.6 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.5 (build 02842) Firefox/3.5.6
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 GTB6 (.NET CLR 3.5.30729) FBSMTWB
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729) FBSMTWB
Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.5) Gecko/20091109 Ubuntu/9.10 (karmic) Firefox/3.5.5
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8pre) Gecko/20091227 Ubuntu/9.10 (karmic) Firefox/3.5.5
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.5) Gecko/20091114 Gentoo Firefox/3.5.5
Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5
Mozilla/5.0 (Windows; U; Windows NT 6.1; uk; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 MRA 5.5 (build 02842) Firefox/3.5.5
Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.1.5) Gecko/20091102 MRA 5.5 (build 02842) Firefox/3.5.5
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.5) Gecko/Firefox/3.5.5
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.5) Gecko/20091102 MRA 5.5 (build 02842) Firefox/3.5.5 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.5) Gecko/20091102 MRA 5.5 (build 02842) Firefox/3.5.5
Mozilla/5.0 (Windows NT 5.1; U; zh-cn; rv:1.8.1) Gecko/20091102 Firefox/3.5.5
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; pl; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 FBSMTWB
Mozilla/5.0 (X11; U; Linux x86_64; ja; rv:1.9.1.4) Gecko/20091016 SUSE/3.5.4-1.1.2 Firefox/3.5.4
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 (.NET CLR 3.5.30729) FBSMTWB
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.4) Gecko/20091007 Firefox/3.5.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 ( .NET CLR 3.5.30729; .NET4.0E)
Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.4) Gecko/20091007 Firefox/3.5.4
Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.5) Gecko/20091109 Ubuntu/9.10 (karmic) Firefox/3.5.3pre
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090914 Slackware/13.0_stable Firefox/3.5.3
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3
Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.1.3) Gecko/20091020 Ubuntu/9.10 (karmic) Firefox/3.5.3
Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.3) Gecko/20090919 Firefox/3.5.3
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.3) Gecko/20090912 Gentoo Firefox/3.5.3 FirePHP/0.3
Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 GTB5
Mozilla/5.0 (X11; U; FreeBSD i386; ru-RU; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.5.3;MEGAUPLOAD 1.0 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Mozilla/5.0 (Windows; U; Windows NT 6.0; ko; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; fi; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 2.0.50727; .NET CLR 3.0.30618; .NET CLR 3.5.21022; .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; bg; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; pl; rv:1.9.1.2) Gecko/20090911 Slackware Firefox/3.5.2
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.2) Gecko/20090803 Slackware Firefox/3.5.2
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.2) Gecko/20090803 Firefox/3.5.2 Slackware
Mozilla/5.0 (X11; U; Linux i686; ru-RU; rv:1.9.1.2) Gecko/20090804 Firefox/3.5.2
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.2) Gecko/20090729 Slackware/13.0 Firefox/3.5.2
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Mozilla/5.0 (X11; U; Linux i686 (x86_64); fr; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB7.1 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; es-MX; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Mozilla/5.0 (Windows; U; Windows NT 5.1; uk; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2
Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 FirePHP/0.4
Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1.16) Gecko/20101130 AskTbMYC/3.9.1.14019 Firefox/3.5.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; it; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 GTB7.1 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.16) Gecko/20101130 MRA 5.4 (build 02647) Firefox/3.5.16 ( .NET CLR 3.5.30729; .NET4.0C)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 GTB7.1
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.16) Gecko/20101130 AskTbPLTV5/3.8.0.12304 Firefox/3.5.16 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 GTB7.1 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 GTB7.1
Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.1.15) Gecko/20101027 Fedora/3.5.15-1.fc12 Firefox/3.5.15
Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.15) Gecko/20101027 Fedora/3.5.15-1.fc12 Firefox/3.5.15
Mozilla/5.0 (Windows; U; Windows NT 5.0; ru; rv:1.9.1.13) Gecko/20100914 Firefox/3.5.13
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.12) Gecko/2009070611 Firefox/3.5.12
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.12) Gecko/20100824 MRA 5.7 (build 03755) Firefox/3.5.12
Mozilla/5.0 (X11; U; Linux; en-US; rv:1.9.1.11) Gecko/20100720 Firefox/3.5.11
Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1.11) Gecko/20100701 Firefox/3.5.11 ( .NET CLR 3.5.30729; .NET4.0C)
Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR; rv:1.9.1.11) Gecko/20100701 Firefox/3.5.11 ( .NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 5.1; hu; rv:1.9.1.11) Gecko/20100701 Firefox/3.5.11
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.10) Gecko/20100504 Firefox/3.5.11 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.1.10) Gecko/20100506 SUSE/3.5.10-0.1.1 Firefox/3.5.10
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.10) Gecko/20100504 Firefox/3.5.10 GTB7.0 ( .NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux x86_64; rv:1.9.1.1) Gecko/20090716 Linux Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100524 Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Linux Mint/7 (Gloria) Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090714 SUSE/3.5.1-1.1 Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux x86; rv:1.9.1.1) Gecko/20090716 Linux Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.2pre) Gecko/20090729 Ubuntu/9.04 (jaunty) Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.1) Gecko/20090722 Gentoo Firefox/3.5.1
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.1) Gecko/20090714 SUSE/3.5.1-1.1 Firefox/3.5.1
Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1) Gecko/20090720 Firefox/3.5.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; tr; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; sv-SE; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5 (.NET CLR 4.0.20506)
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11;U; Linux i686; en-GB; rv:1.9.1) Gecko/20090624 Ubuntu/9.04 (jaunty) Firefox/3.5
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1) Gecko/20090630 Firefox/3.5 GTB6
Mozilla/5.0 (X11; U; Linux i686; ja; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.04 (jaunty) Firefox/3.5
Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.1) Gecko/20090624 Firefox/3.5
Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.9.1) Gecko/20090624 Ubuntu/9.04 (jaunty) Firefox/3.5
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1) Gecko/20090701 Ubuntu/9.04 (jaunty) Firefox/3.5
Mozilla/5.0 (X11; U; Linux i686; en-us; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.04 (jaunty) Firefox/3.5
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1) Gecko/20090624 Ubuntu/8.04 (hardy) Firefox/3.5
Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1) Gecko/20090624 Firefox/3.5
Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.9.1) Gecko/20090624 Firefox/3.5
Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.1) Gecko/20090703 Firefox/3.5
Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.0.10) Gecko/20090624 Firefox/3.5
Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1) Gecko/20090612 Firefox/3.5 (.NET CLR 4.0.20506)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1) Gecko/20090612 Firefox/3.5
Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 4.0.20506)
Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1) Gecko/20090624 Firefox/3.5
Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-TW; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.25 (KHTML, like Gecko) Chrome/12.0.706.0 Safari/534.25
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24
Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.702.0 Chrome/12.0.702.0 Safari/534.24
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/12.0.702.0 Safari/534.24
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/12.0.702.0 Safari/534.24
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.699.0 Safari/534.24
Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.699.0 Safari/534.24
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.698.0 Safari/534.24
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.697.0 Safari/534.24
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.43 Safari/534.24
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24
Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24
Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24
Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.14 Safari/534.24
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.12 Safari/534.24
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.12 Safari/534.24
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.04 Chromium/11.0.696.0 Chrome/11.0.696.0 Safari/534.24
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.0 Safari/534.24
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.694.0 Safari/534.24
Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.23 (KHTML, like Gecko) Chrome/11.0.686.3 Safari/534.23
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.21 (KHTML, like Gecko) Chrome/11.0.682.0 Safari/534.21
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.21 (KHTML, like Gecko) Chrome/11.0.678.0 Safari/534.21
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_7_0; en-US) AppleWebKit/534.21 (KHTML, like Gecko) Chrome/11.0.678.0 Safari/534.21
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20
Mozilla/5.0 (Windows NT) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.669.0 Safari/534.20
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.19 (KHTML, like Gecko) Chrome/11.0.661.0 Safari/534.19
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.18 (KHTML, like Gecko) Chrome/11.0.661.0 Safari/534.18
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.18 (KHTML, like Gecko) Chrome/11.0.660.0 Safari/534.18
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.655.0 Safari/534.17
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.655.0 Safari/534.17
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.654.0 Safari/534.17
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.652.0 Safari/534.17
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/10.0.649.0 Safari/534.17
Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/10.0.649.0 Safari/534.17
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.82 Safari/534.16
Mozilla/5.0 (X11; U; Linux armv7l; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Mozilla/5.0 (X11; U; FreeBSD x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Mozilla/5.0 (X11; U; FreeBSD i386; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134 Safari/534.16
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134 Safari/534.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134 Safari/534.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.133 Chrome/10.0.648.133 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.133 Chrome/10.0.648.133 Safari/534.16
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.127 Chrome/10.0.648.127 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127 Safari/534.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127 Safari/534.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.11 Safari/534.16
Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.11 Safari/534.16
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.11 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.0 Chrome/10.0.648.0 Safari/534.16
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.0 Chrome/10.0.648.0 Safari/534.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.0 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.642.0 Chrome/10.0.642.0 Safari/534.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.639.0 Safari/534.16
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.638.0 Safari/534.16
Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.634.0 Safari/534.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.634.0 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 SUSE/10.0.626.0 (KHTML, like Gecko) Chrome/10.0.626.0 Safari/534.16
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Chrome/10.0.613.0 Safari/534.15
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.613.0 Chrome/10.0.613.0 Safari/534.15
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Ubuntu/10.04 Chromium/10.0.612.3 Chrome/10.0.612.3 Safari/534.15
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Chrome/10.0.612.1 Safari/534.15
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.611.0 Chrome/10.0.611.0 Safari/534.15
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.602.0 Safari/534.14
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.601.0 Safari/534.14
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.601.0 Safari/534.14
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/540.0 (KHTML,like Gecko) Chrome/9.1.0.0 Safari/540.0
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/540.0 (KHTML, like Gecko) Ubuntu/10.10 Chrome/9.1.0.0 Safari/540.0
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 Safari/534.14
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Ubuntu/10.10 Chromium/9.0.600.0 Chrome/9.0.600.0 Safari/534.14
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.600.0 Safari/534.14
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.599.0 Safari/534.13
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.84 Safari/534.13
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.44 Safari/534.13
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.19 Safari/534.13
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.15 Safari/534.13
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.15 Safari/534.13
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.596.0 Safari/534.13
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Ubuntu/10.04 Chromium/9.0.595.0 Chrome/9.0.595.0 Safari/534.13
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Ubuntu/9.10 Chromium/9.0.592.0 Chrome/9.0.592.0 Safari/534.13
Mozilla/5.0 (X11; U; Windows NT 6; en-US) AppleWebKit/534.12 (KHTML, like Gecko) Chrome/9.0.587.0 Safari/534.12
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.12 (KHTML, like Gecko) Chrome/9.0.579.0 Safari/534.12
Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US) AppleWebKit/534.12 (KHTML, like Gecko) Chrome/9.0.576.0 Safari/534.12
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/540.0 (KHTML, like Gecko) Ubuntu/10.10 Chrome/8.1.0.0 Safari/540.0
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.558.0 Safari/534.10
Mozilla/5.0 (X11; U; CrOS i686 0.9.130; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.344 Safari/534.10
Mozilla/5.0 (X11; U; CrOS i686 0.9.128; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.343 Safari/534.10
Mozilla/5.0 (X11; U; CrOS i686 0.9.128; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.341 Safari/534.10
Mozilla/5.0 (X11; U; CrOS i686 0.9.128; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.339 Safari/534.10
Mozilla/5.0 (X11; U; CrOS i686 0.9.128; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.339
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Ubuntu/10.10 Chromium/8.0.552.237 Chrome/8.0.552.237 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.3 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/533.3
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.210 Safari/534.10
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.200 Safari/534.10
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.551.0 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.548.0 Safari/534.10
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.544.0 Safari/534.10
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101027 Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.540.0 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.540.0 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.540.0 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.540.0 Safari/534.10
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.9 (KHTML, like Gecko) Chrome/7.0.531.0 Safari/534.9
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.8 (KHTML, like Gecko) Chrome/7.0.521.0 Safari/534.8
Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.24 Safari/534.7
Mozilla/5.0 (X11; U; Linux x86_64; fr-FR) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7
Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.6 (KHTML, like Gecko) Chrome/7.0.500.0 Safari/534.6
Mozilla/5.0 (Windows; U; Windows NT 6.1; tr-TR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Windows; U; Windows NT 6.1; ko-KR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Windows; U; Windows NT 6.1; fr-FR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Windows; U; Windows NT 6.1; cs-CZ) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; zh-cn) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; zh-cn) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; sv-se) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; ko-kr) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; it-it) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; fr-fr) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; es-es) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-us) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-gb) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; de-de) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
Mozilla/5.0 (Windows; U; Windows NT 6.1; sv-SE) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 6.1; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 6.0; hu-HU) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 6.0; de-DE) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; it-IT) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/534.16+ (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; fr-ch) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; de-de) AppleWebKit/534.15+ (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ar) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Android 2.2; Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-HK) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Mozilla/5.0 (Windows; U; Windows NT 6.0; tr-TR) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Mozilla/5.0 (Windows; U; Windows NT 6.0; nb-NO) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-FR) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; zh-cn) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5
Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8G4 Safari/6533.18.5
Mozilla/5.0 (iPod; U; CPU iPhone OS 4_2_1 like Mac OS X; he-il) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5
Mozilla/5.0 (iPhone; U; fr; CPU iPhone OS 4_2_1 like Mac OS X; fr) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_1 like Mac OS X; zh-tw) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8G4 Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3 like Mac OS X; pl-pl) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3 like Mac OS X; fr-fr) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3 like Mac OS X; en-gb) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; nb-no) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; it-it) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; fr) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; fi-fi) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; fi-fi) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; th-th) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8
Mozilla/5.0 (X11; U; Linux x86_64; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+
Mozilla/5.0 (X11; U; Linux x86_64; en-ca) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+
Mozilla/5.0 (Windows; U; Windows NT 6.1; ja-JP) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; ja-jp) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; fr) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; zh-cn) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ru-ru) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ko-kr) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; it-it) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/534.1+ (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-au) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; el-gr) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ca-es) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; zh-tw) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; ja-jp) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; it-it) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; fr-fr) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-en) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; nl-nl) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; ja-jp) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; de-de) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_7; en-us) AppleWebKit/533.4 (KHTML, like Gecko) Version/4.1 Safari/533.4
Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/526.9 (KHTML, like Gecko) Version/4.0dp1 Safari/526.8
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; tr) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; en) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; de) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081212 Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/526.9 (KHTML, like Gecko) Version/4.0dp1 Safari/526.8
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-gb) AppleWebKit/528.10+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_4; en-us) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_4; en-gb) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2
Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-gb) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Windows; U; Windows NT 5.1; cs-CZ) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; en-us) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; da-dk) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ja-jp) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/533.4+ (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; de-de) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; ja-jp) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; nl-nl) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B5097d Safari/6531.22.7
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7
Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10gin_lib.cc
Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10
Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/123
Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-TW) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (Windows; U; Windows NT 6.1; ko-KR) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE) AppleWebKit/532+ (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; hu-hu) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/531.21.11 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; ru-ru) AppleWebKit/533.2+ (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; de-at) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Mozilla/5.0 (iPhone; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10
Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7D11 Safari/531.21.10
Mozilla/5.0 (iPad; U; CPU OS 3_2_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B500 Safari/53
Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; es-es) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10
Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; es-es) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B360 Safari/531.21.10
Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.1021.10gin_lib.cc
Mozilla/5.0 (iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; en-us) AppleWebKit/532.0+ (KHTML, like Gecko) Version/4.0.3 Safari/531.9.2009
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; en-us) AppleWebKit/532.0+ (KHTML, like Gecko) Version/4.0.3 Safari/531.9
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_1; nl-nl) AppleWebKit/532.3+ (KHTML, like Gecko) Version/4.0.3 Safari/531.9
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; fi-fi) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.3 Safari/531.21.10
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532+ (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-TW) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; pl-PL) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-FR) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 5.2; de-DE) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1
Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_7; en-us) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/4.0.1 Safari/530.18
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.1 Safari/530.18
Mozilla/5.0 (Windows; U; Windows NT 6.0; ru-RU) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; hu-HU) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; he-IL) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; he-IL) AppleWebKit/528+ (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-FR) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; es-es) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; en) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 6.0; de-DE) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-PT) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; nb-NO) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; hu-HU) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; fr-FR) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Mozilla/5.0 (Windows; U; Windows NT 5.1; fi-FI) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16
Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.10
Opera/9.80 (Windows NT 5.1; U; zh-tw) Presto/2.8.131 Version/11.10
Opera/9.80 (X11; Linux x86_64; U; Ubuntu/10.10 (maverick); pl) Presto/2.7.62 Version/11.01
Opera/9.80 (X11; Linux i686; U; ja) Presto/2.7.62 Version/11.01
Opera/9.80 (X11; Linux i686; U; fr) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 6.1; U; sv) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 6.1; U; en-US) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 6.1; U; cs) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 5.1; U;) Presto/2.7.62 Version/11.01
Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.7.62 Version/11.01
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101213 Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01
Mozilla/5.0 (Windows NT 6.1; U; nl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.01
Mozilla/5.0 (Windows NT 6.1; U; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.01
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; de) Opera 11.01
Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.00
Opera/9.80 (X11; Linux i686; U; it) Presto/2.7.62 Version/11.00
Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.6.37 Version/11.00
Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.7.62 Version/11.00
Opera/9.80 (Windows NT 6.1; U; ko) Presto/2.7.62 Version/11.00
Opera/9.80 (Windows NT 6.1; U; fi) Presto/2.7.62 Version/11.00
Opera/9.80 (Windows NT 6.1; U; en-GB) Presto/2.7.62 Version/11.00
Opera/9.80 (Windows NT 6.1 x64; U; en) Presto/2.7.62 Version/11.00
Opera/9.80 (Windows NT 6.0; U; en) Presto/2.7.39 Version/11.00
Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.39 Version/11.00
Opera/9.80 (Windows NT 5.1; U; MRA 5.5 (build 02842); ru) Presto/2.7.62 Version/11.00
Opera/9.80 (Windows NT 5.1; U; it) Presto/2.7.62 Version/11.00
Mozilla/5.0 (Windows NT 6.0; U; ja; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.00
Mozilla/5.0 (Windows NT 5.1; U; pl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.00
Mozilla/5.0 (Windows NT 5.1; U; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.00
Mozilla/4.0 (compatible; MSIE 8.0; X11; Linux x86_64; pl) Opera 11.00
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; fr) Opera 11.00
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; ja) Opera 11.00
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; en) Opera 11.00
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; pl) Opera 11.00
Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.6.31 Version/10.70
Mozilla/5.0 (Windows NT 5.2; U; ru; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.70
Mozilla/5.0 (Windows NT 5.1; U; zh-cn; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.70
Opera/9.80 (Windows NT 5.2; U; zh-cn) Presto/2.6.30 Version/10.63
Opera/9.80 (Windows NT 5.2; U; en) Presto/2.6.30 Version/10.63
Opera/9.80 (Windows NT 5.1; U; MRA 5.6 (build 03278); ru) Presto/2.6.30 Version/10.63
Opera/9.80 (Windows NT 5.1; U; pl) Presto/2.6.30 Version/10.62
Mozilla/5.0 (X11; Linux x86_64; U; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.62
Mozilla/4.0 (compatible; MSIE 8.0; X11; Linux x86_64; de) Opera 10.62
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; en) Opera 10.62
Opera/9.80 (X11; Linux i686; U; pl) Presto/2.6.30 Version/10.61
Opera/9.80 (X11; Linux i686; U; es-ES) Presto/2.6.30 Version/10.61
Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.6.30 Version/10.61
Opera/9.80 (Windows NT 6.1; U; en) Presto/2.6.30 Version/10.61
Opera/9.80 (Windows NT 6.0; U; it) Presto/2.6.30 Version/10.61
Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.6.30 Version/10.61
Opera/9.80 (Windows 98; U; de) Presto/2.6.30 Version/10.61
Opera/9.80 (Macintosh; Intel Mac OS X; U; nl) Presto/2.6.30 Version/10.61
Opera/9.80 (X11; Linux i686; U; en) Presto/2.5.27 Version/10.60
Opera/9.80 (Windows NT 6.0; U; nl) Presto/2.6.30 Version/10.60
Opera/10.60 (Windows NT 5.1; U; zh-cn) Presto/2.6.30 Version/10.60
Opera/10.60 (Windows NT 5.1; U; en-US) Presto/2.6.30 Version/10.60
Opera/9.80 (X11; Linux i686; U; it) Presto/2.5.24 Version/10.54
Opera/9.80 (X11; Linux i686; U; en-GB) Presto/2.5.24 Version/10.53
Mozilla/5.0 (Windows NT 5.1; U; zh-cn; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53
Mozilla/5.0 (Windows NT 5.1; U; Firefox/5.0; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53
Mozilla/5.0 (Windows NT 5.1; U; Firefox/4.5; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53
Mozilla/5.0 (Windows NT 5.1; U; Firefox/3.5; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; ko) Opera 10.53
Opera/9.80 (Windows NT 6.1; U; fr) Presto/2.5.24 Version/10.52
Opera/9.80 (Windows NT 6.1; U; en) Presto/2.5.22 Version/10.51
Opera/9.80 (Windows NT 6.0; U; cs) Presto/2.5.22 Version/10.51
Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51
Opera/9.80 (Linux i686; U; en) Presto/2.5.22 Version/10.51
Mozilla/5.0 (Windows NT 6.1; U; en-GB; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.51
Mozilla/5.0 (Linux i686; U; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.51
Mozilla/4.0 (compatible; MSIE 8.0; Linux i686; en) Opera 10.51
Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.5.22 Version/10.50
Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.5.22 Version/10.50
Opera/9.80 (Windows NT 6.1; U; sk) Presto/2.6.22 Version/10.50
Opera/9.80 (Windows NT 6.1; U; ja) Presto/2.5.22 Version/10.50
Opera/9.80 (Windows NT 6.0; U; zh-cn) Presto/2.5.22 Version/10.50
Opera/9.80 (Windows NT 5.1; U; sk) Presto/2.5.22 Version/10.50
Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.5.22 Version/10.50
Opera/10.50 (Windows NT 6.1; U; en-GB) Presto/2.2.2
Opera/9.80 (S60; SymbOS; Opera Tablet/9174; U; en) Presto/2.7.81 Version/10.5
Opera/9.80 (X11; U; Linux i686; en-US; rv:1.9.2.3) Presto/2.2.15 Version/10.10
Opera/9.80 (X11; Linux x86_64; U; it) Presto/2.2.15 Version/10.10
Opera/9.80 (Windows NT 6.1; U; de) Presto/2.2.15 Version/10.10
Opera/9.80 (Windows NT 6.0; U; Gecko/20100115; pl) Presto/2.2.15 Version/10.10
Opera/9.80 (Windows NT 6.0; U; en) Presto/2.2.15 Version/10.10
Opera/9.80 (Windows NT 5.1; U; de) Presto/2.2.15 Version/10.10
Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.2.15 Version/10.10
Mozilla/5.0 (Windows NT 6.0; U; tr; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 10.10
Mozilla/4.0 (compatible; MSIE 6.0; X11; Linux i686; de) Opera 10.10
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.0; tr) Opera 10.10
Opera/9.80 (X11; Linux x86_64; U; en-GB) Presto/2.2.15 Version/10.01
Opera/9.80 (X11; Linux x86_64; U; en) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux x86_64; U; de) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux i686; U; ru) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux i686; U; pt-BR) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux i686; U; pl) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux i686; U; nb) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux i686; U; en-GB) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux i686; U; en) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux i686; U; Debian; pl) Presto/2.2.15 Version/10.00
Opera/9.80 (X11; Linux i686; U; de) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 6.1; U; fi) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 6.1; U; en) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 6.1; U; de) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 6.1; U; cs) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 6.0; U; en) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 6.0; U; de) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 5.2; U; en) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 5.1; U; zh-cn) Presto/2.2.15 Version/10.00
Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.2.15 Version/10.00

View File

View File

@ -0,0 +1 @@
from .motorbase import MotorBase, MotorBaseOld, PyMongoDb

View File

@ -0,0 +1,140 @@
#!/usr/bin/env python
import asyncio
from pymongo import MongoClient
from motor.motor_asyncio import AsyncIOMotorClient
from soulbook.config import CONFIG
from soulbook.utils.tools import singleton
@singleton
class MotorBase:
"""
更改mongodb连接方式 单例模式下支持多库操作
About motor's doc: https://github.com/mongodb/motor
"""
_db = {}
_collection = {}
MONGODB = CONFIG.MONGODB
def __init__(self, loop=None):
self.motor_uri = ''
self.loop = loop or asyncio.get_event_loop()
def client(self, db):
# motor
self.motor_uri = 'mongodb://{account}{host}:{port}/{database}'.format(
account='{username}:{password}@'.format(
username=self.MONGODB['MONGO_USERNAME'],
password=self.MONGODB['MONGO_PASSWORD']) if self.MONGODB['MONGO_USERNAME'] else '',
host=self.MONGODB['MONGO_HOST'] if self.MONGODB['MONGO_HOST'] else 'localhost',
port=self.MONGODB['MONGO_PORT'] if self.MONGODB['MONGO_PORT'] else 27017,
database=db)
return AsyncIOMotorClient(self.motor_uri, io_loop=self.loop)
def get_db(self, db=MONGODB['DATABASE']):
"""
Get a db instance
:param db: database name
:return: the motor db instance
"""
if db not in self._db:
self._db[db] = self.client(db)[db]
return self._db[db]
def get_collection(self, db_name, collection):
"""
Get a collection instance
:param db_name: database name
:param collection: collection name
:return: the motor collection instance
"""
collection_key = db_name + collection
if collection_key not in self._collection:
self._collection[collection_key] = self.get_db(db_name)[collection]
return self._collection[collection_key]
class MotorBaseOld:
"""
use motor to connect mongodb
2017-09-21 deleted
"""
_db = None
MONGODB = CONFIG.MONGODB
def client(self, db):
# motor
self.motor_uri = 'mongodb://{account}{host}:{port}/{database}'.format(
account='{username}:{password}@'.format(
username=self.MONGODB['MONGO_USERNAME'],
password=self.MONGODB['MONGO_PASSWORD']) if self.MONGODB['MONGO_USERNAME'] else '',
host=self.MONGODB['MONGO_HOST'] if self.MONGODB['MONGO_HOST'] else 'localhost',
port=self.MONGODB['MONGO_PORT'] if self.MONGODB['MONGO_PORT'] else 27017,
database=db)
return AsyncIOMotorClient(self.motor_uri)
@property
def db(self):
if self._db is None:
self._db = self.client(self.MONGODB['DATABASE'])[self.MONGODB['DATABASE']]
return self._db
@singleton
class PyMongoDb:
_db = None
MONGODB = {
'MONGO_HOST': '127.0.0.1',
'MONGO_PORT': '',
'MONGO_USERNAME': '',
'MONGO_PASSWORD': '',
'DATABASE': 'soulbook'
}
def client(self):
# motor
self.mongo_uri = 'mongodb://{account}{host}:{port}/'.format(
account='{username}:{password}@'.format(
username=self.MONGODB['MONGO_USERNAME'],
password=self.MONGODB['MONGO_PASSWORD']) if self.MONGODB['MONGO_USERNAME'] else '',
host=self.MONGODB['MONGO_HOST'] if self.MONGODB['MONGO_HOST'] else 'localhost',
port=self.MONGODB['MONGO_PORT'] if self.MONGODB['MONGO_PORT'] else 27017)
return MongoClient(self.mongo_uri)
@property
def db(self):
if self._db is None:
self._db = self.client()[self.MONGODB['DATABASE']]
return self._db
if __name__ == '__main__':
def async_callback(func, **kwargs):
"""
Call the asynchronous function
:param func: a async function
:param kwargs: params
:return: result
"""
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(func(**kwargs))
loop.run_until_complete(task)
return task.result()
motor_base = MotorBase()
motor_db = motor_base.get_db()
async def insert(data):
print(data)
await motor_db.test.save(data)
async_callback(insert, data={'hi': 'soulbook'})

View File

@ -0,0 +1 @@
from .redisbase import *

View File

@ -0,0 +1,24 @@
#!/usr/bin/env python
import asyncio_redis
from soulbook.config import CONFIG
# Token from https://github.com/subyraman/sanic_session
class RedisSession:
"""
A simple wrapper class that allows you to share a connection
pool across your application.
"""
_pool = None
async def get_redis_pool(self):
if not self._pool:
REDIS_DICT = CONFIG.REDIS_DICT
self._pool = await asyncio_redis.Pool.create(
host=str(REDIS_DICT.get('REDIS_ENDPOINT', "localhost")), port=int(REDIS_DICT.get('REDIS_PORT', 6379)),
poolsize=int(REDIS_DICT.get('POOLSIZE', 10)), password=REDIS_DICT.get('REDIS_PASSWORD', None),
db=REDIS_DICT.get('SESSION_DB', None)
)
return self._pool

View File

@ -0,0 +1 @@
from .response_base import UniResponse, ResponseReply, ResponseCode, ResponseField

294
soulbook/fetcher/cache.py Normal file
View File

@ -0,0 +1,294 @@
#!/usr/bin/env python
"""
Created by howie.hu.
"""
import re
import aiohttp
import async_timeout
from bs4 import BeautifulSoup
from aiocache.serializers import PickleSerializer, JsonSerializer
from urllib.parse import urlparse, parse_qs, urljoin
from soulbook.database.mongodb import MotorBase
from soulbook.fetcher.decorators import cached
from soulbook.fetcher.function import target_fetch, get_time, get_html_by_requests, \
get_random_user_agent
from soulbook.fetcher.extract_novels import extract_pre_next_chapter
from soulbook.config import RULES, LATEST_RULES, LOGGER
list_class_content = ("content", "content_read", "txt")
list_id_content = ("chaptercontent", "content", "txt")
@cached(ttl=300, key_from_attr='url', serializer=PickleSerializer(), namespace="main")
async def cache_owllook_novels_content(url, chapter_url, netloc):
headers = {
'user-agent': await get_random_user_agent()
}
html = await target_fetch(headers=headers, url=url)
if not html:
html = get_html_by_requests(url=url, headers=headers)
if html:
soup = BeautifulSoup(html, 'html5lib')
# 章节内容
content = None
if RULES.get(netloc):
selector = RULES[netloc].content_selector
if selector.get('id', None):
content = soup.find_all(id_=selector['id'])
elif selector.get('class', None):
content = soup.find_all(class_=selector['class'])
else:
content = soup.find_all(selector.get('tag'))
if not content:
# print("novels_content: body")
# content = soup.find_all("body")
# for i in list_class_content:
# content = soup.find_all(class_=i)
# if content:
# break
# else:
# for i in list_id_content:
# content = soup.find_all(id=i)
# if content:
# break
for i in list_id_content:
content = soup.find_all(id=i)
if content:
break
else:
for i in list_class_content:
content = soup.find_all(class_=i)
if content:
break
if not content:
# 直接提取整个版块块
content = soup.find_all("body")
if content:
# 提取出真正的章节标题
title_reg = r'(第?\s*[一二两三四五六七八九十○零百千万亿0-9]{1,6}\s*[章回卷节折篇幕集]\s*.*?)[_,-]'
title = soup.title.string
extract_title = re.findall(title_reg, title, re.I)
if extract_title:
title = extract_title[0]
else:
try:
title = soup.select('h1')[0].get_text()
except Exception as e:
print(e)
if not title:
title = soup.title.string
# if "_" in title:
# title = title.split('_')[0]
# elif "-" in title:
# title = title.split('-')[0]
next_chapter = extract_pre_next_chapter(url=url, chapter_url=chapter_url,
html=str(soup))
content = [str(i) for i in content]
data = {
'content': str(''.join(content)),
'next_chapter': next_chapter,
'title': title
}
else:
data = None
return data
return None
ListIdTab = ("box_con", 'box_chap', 'layout layout-col1', 'listmain', "content", "list-chapterAll")
ListClassTab = (
"box_con", 'box_chap', 'layout layout-col1', 'listmain', 'book chapterlist', 'book_list',
'TabCss', 'inner', 'mulu', 'bg')
@cached(ttl=300, key_from_attr='url', serializer=PickleSerializer(), namespace="main")
async def cache_owllook_novels_chapter(url, netloc):
headers = {
'user-agent': await get_random_user_agent()
}
html = await target_fetch(headers=headers, url=url)
if not html:
html = get_html_by_requests(url=url, headers=headers)
if html:
soup = BeautifulSoup(html, 'html5lib')
# 提取出的内容
content = None
# 存在解析规则
if RULES.get(netloc):
# 匹配解析规则
selector = RULES[netloc].chapter_selector
if selector.get('id', None):
content = soup.find_all(id=selector['id'])
elif selector.get('class', None):
content = soup.find_all(class_=selector['class'])
else:
content = soup.find_all(selector.get('tag'))
else:
data = str(html)
for i in ListIdTab:
if 'id="%s"' % i in data:
content = soup.find_all(id=i)
break
for i in ListClassTab:
if 'class="%s"' % i in data:
content = soup.find_all(class_=i)
break
if not content:
# 直接提取整个版块块
content = soup.find_all("body")
if content:
# 防止章节被display:none
return str(content).replace('style', '') if content else None
return None
@cached(ttl=10800, key_from_attr='search_ranking', serializer=JsonSerializer(), namespace="ranking")
async def cache_owllook_search_ranking():
motor_db = MotorBase().get_db()
keyword_cursor = motor_db.search_records.find(
{'count': {'$gte': 50}},
{'keyword': 1, 'count': 1, '_id': 0}
).sort('count', -1).limit(35)
result = []
index = 1
async for document in keyword_cursor:
result.append({'keyword': document['keyword'], 'count': document['count'], 'index': index})
index += 1
return result
@cached(ttl=3600, key_from_attr='search_ranking', serializer=JsonSerializer(), namespace="ranking")
async def cache_others_search_ranking(spider='qidian', novel_type='全部类别'):
motor_db = MotorBase().get_db()
item_data = await motor_db.novels_ranking.find_one({'spider': spider, 'type': novel_type},
{'data': 1, '_id': 0})
return item_data
async def get_the_latest_chapter(chapter_url, timeout=15):
try:
with async_timeout.timeout(timeout):
url = parse_qs(urlparse(chapter_url).query).get('url', '')
novels_name = parse_qs(urlparse(chapter_url).query).get('novels_name', '')
data = None
if url and novels_name:
url = url[0]
novels_name = novels_name[0]
netloc = urlparse(url).netloc
if netloc in LATEST_RULES.keys():
headers = {
'user-agent': await get_random_user_agent()
}
try:
html = await target_fetch(url=url, headers=headers, timeout=timeout)
if html is None:
html = get_html_by_requests(url=url, headers=headers, timeout=timeout)
except TypeError:
html = get_html_by_requests(url=url, headers=headers, timeout=timeout)
except Exception as e:
LOGGER.exception(e)
return None
try:
soup = BeautifulSoup(html, 'html5lib')
except Exception as e:
LOGGER.exception(e)
return None
latest_chapter_name, latest_chapter_url = None, None
if LATEST_RULES[netloc].plan:
meta_value = LATEST_RULES[netloc].meta_value
latest_chapter_name = soup.select(
'meta[property="{0}"]'.format(
meta_value["latest_chapter_name"])) or soup.select(
'meta[name="{0}"]'.format(meta_value["latest_chapter_name"]))
latest_chapter_name = latest_chapter_name[0].get('content',
None) if latest_chapter_name else None
latest_chapter_url = soup.select(
'meta[property="{0}"]'.format(
meta_value["latest_chapter_url"])) or soup.select(
'meta[name="{0}"]'.format(meta_value["latest_chapter_url"]))
latest_chapter_url = urljoin(chapter_url,
latest_chapter_url[0].get('content',
None)) if latest_chapter_url else None
else:
selector = LATEST_RULES[netloc].selector
content_url = selector.get('content_url')
if selector.get('id', None):
latest_chapter_soup = soup.find_all(id=selector['id'])
elif selector.get('class', None):
latest_chapter_soup = soup.find_all(class_=selector['class'])
else:
latest_chapter_soup = soup.select(selector.get('tag'))
if latest_chapter_soup:
if content_url == '1':
# TODO
pass
elif content_url == '0':
# TODO
pass
else:
latest_chapter_url = content_url + latest_chapter_soup[0].get(
'href', None)
latest_chapter_name = latest_chapter_soup[0].get('title', None)
if latest_chapter_name and latest_chapter_url:
time_current = get_time()
# print(latest_chapter_url)
data = {
"latest_chapter_name": latest_chapter_name,
"latest_chapter_url": latest_chapter_url,
"owllook_chapter_url": chapter_url,
"owllook_content_url": "/owllook_content?url={latest_chapter_url}&name={name}&chapter_url={chapter_url}&novels_name={novels_name}".format(
latest_chapter_url=latest_chapter_url,
name=latest_chapter_name,
chapter_url=url,
novels_name=novels_name,
),
}
# 存储最新章节
motor_db = MotorBase().get_db()
await motor_db.latest_chapter.update_one(
{"novels_name": novels_name, 'owllook_chapter_url': chapter_url},
{'$set': {'data': data, "finished_at": time_current}}, upsert=True)
return data
except Exception as e:
LOGGER.exception(e)
return None
async def update_all_books(loop, timeout=15):
try:
motor_db = MotorBase().get_db()
# 获取所有书架链接游标
books_url_cursor = motor_db.user_message.find({}, {'books_url.book_url': 1, '_id': 0})
book_urls = []
already_urls = set()
async for document in books_url_cursor:
if document:
books_url = document['books_url']
for book_url in books_url:
chapter_url = book_url['book_url']
if chapter_url not in already_urls:
try:
await get_the_latest_chapter(chapter_url, timeout)
except Exception as e:
LOGGER.exception(e)
already_urls.add(chapter_url)
# 一组书架链接列表数据
# book_urls += [book_url['book_url'] for book_url in books_url]
# url_tasks = [get_the_latest_chapter(each_url, loop) for each_url in set(book_urls)]
# tasks = [asyncio.ensure_future(i) for i in url_tasks]
# try:
# await asyncio.gather(*tasks)
# except asyncio.TimeoutError as e:
# pass
except Exception as e:
LOGGER.exception(e)
return False

View File

@ -0,0 +1,153 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
from functools import wraps
from sanic import response
from aiocache.log import logger
from aiocache.utils import get_args_dict, get_cache
from sanic.request import Request
try:
from ujson import loads as json_loads
from ujson import dumps as json_dumps
except:
from json import loads as json_loads
from json import dumps as json_dumps
from soulbook.fetcher import UniResponse
from soulbook.config import CONFIG, LOGGER
def authenticator(key):
"""
:param keys: 验证方式 Owllook-Api-Key : Magic Key, Authorization : Token
:return: 返回值
"""
def wrapper(func):
@wraps(func)
async def authenticate(request, *args, **kwargs):
value = request.headers.get(key, None)
if value and CONFIG.AUTH[key] == value:
response = await func(request, *args, **kwargs)
return response
else:
return response_handle(request, UniResponse.NOT_AUTHORIZED, status=401)
return authenticate
return wrapper
def auth_params(*keys):
"""
:param keys: 判断必须要有的参数
:return: 返回值
"""
def wrapper(func):
@wraps(func)
async def auth_param(request, *args, **kwargs):
request_params = {}
# POST request
if request.method == 'POST' or request.method == 'DELETE':
try:
post_data = json_loads(str(request.body, encoding='utf-8'))
except Exception as e:
LOGGER.exception(e)
return response_handle(request, UniResponse.PARAM_PARSE_ERR, status=400)
else:
request_params.update(post_data)
params = [key for key, value in post_data.items() if value]
elif request.method == 'GET':
request_params.update(request.args)
params = [key for key, value in request.args.items() if value]
else:
# TODO
return response_handle(request, UniResponse.PARAM_UNKNOWN_ERR, status=400)
if set(keys).issubset(set(params)):
try:
kwargs['request_params'] = request_params
response = await func(request, *args, **kwargs)
return response
except Exception as e:
LOGGER.exception(e)
return response_handle(request, UniResponse.SERVER_UNKNOWN_ERR, 500)
else:
return response_handle(request, UniResponse.PARAM_ERR, status=400)
return auth_param
return wrapper
# Token from https://github.com/argaen/aiocache/blob/master/aiocache/decorators.py
def cached(
ttl=0, key=None, key_from_attr=None, cache=None, serializer=None, plugins=None, **kwargs):
"""
Caches the functions return value into a key generated with module_name, function_name and args.
In some cases you will need to send more args to configure the cache object.
An example would be endpoint and port for the RedisCache. You can send those args as
kwargs and they will be propagated accordingly.
:param ttl: int seconds to store the function call. Default is 0 which means no expiration.
:param key: str value to set as key for the function return. Takes precedence over
key_from_attr param. If key and key_from_attr are not passed, it will use module_name
+ function_name + args + kwargs
:param key_from_attr: arg or kwarg name from the function to use as a key.
:param cache: cache class to use when calling the ``set``/``get`` operations.
Default is the one configured in ``aiocache.settings.DEFAULT_CACHE``
:param serializer: serializer instance to use when calling the ``dumps``/``loads``.
Default is the one configured in ``aiocache.settings.DEFAULT_SERIALIZER``
:param plugins: plugins to use when calling the cmd hooks
Default is the one configured in ``aiocache.settings.DEFAULT_PLUGINS``
"""
cache_kwargs = kwargs
def cached_decorator(func):
async def wrapper(*args, **kwargs):
cache_instance = get_cache(
cache=cache, serializer=serializer, plugins=plugins, **cache_kwargs)
args_dict = get_args_dict(func, args, kwargs)
cache_key = key or args_dict.get(
key_from_attr,
(func.__module__ or 'stub') + func.__name__ + str(args) + str(kwargs))
try:
if await cache_instance.exists(cache_key):
return await cache_instance.get(cache_key)
except Exception:
logger.exception("Unexpected error with %s", cache_instance)
result = await func(*args, **kwargs)
if result:
try:
await cache_instance.set(cache_key, result, ttl=ttl)
except Exception:
logger.exception("Unexpected error with %s", cache_instance)
return result
return wrapper
return cached_decorator
def response_handle(request, dict_value, status=200):
"""
Return sanic.response or json depending on the request
:param request: sanic.request.Request or dict
:param dict_value:
:return:
"""
if isinstance(request, Request):
return response.json(dict_value, status=status)
else:
return json_dumps(dict_value, ensure_ascii=False)

View File

@ -0,0 +1,85 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
import re
from bs4 import BeautifulSoup
from collections import OrderedDict
from operator import itemgetter
from urllib.parse import urljoin, urlparse
from soulbook.config import LOGGER
def extract_chapters(chapters_url, html):
"""
通用解析小说目录
:param chapter_url: 小说目录页url
:param res: 当前页面html
:return:
"""
# 参考https://greasyfork.org/zh-CN/scripts/292-my-novel-reader
chapters_reg = r'(<a\s+.*?>.*第?\s*[一二两三四五六七八九十○零百千万亿0-9]{1,6}\s*[章回卷节折篇幕集].*?</a>)'
# 这里不能保证获取的章节分得很清楚但能保证这一串str是章节目录。可以利用bs安心提取a
chapters_res = re.findall(chapters_reg, str(html), re.I)
str_chapters_res = '\n'.join(chapters_res)
chapters_res_soup = BeautifulSoup(str_chapters_res, 'html5lib')
all_chapters = []
for link in chapters_res_soup.find_all('a'):
each_data = {}
url = urljoin(chapters_url, link.get('href')) or ''
name = link.text or ''
each_data['chapter_url'] = url
each_data['chapter_name'] = name
each_data['index'] = int(urlparse(url).path.split('.')[0].split('/')[-1])
all_chapters.append(each_data)
chapters_sorted = sorted(all_chapters, reverse=True, key=itemgetter('index'))
return chapters_sorted
def extract_pre_next_chapter(url, chapter_url, html):
"""
获取单章节上一页下一页
:param chapter_url:
:param html:
:return:
"""
next_chapter = OrderedDict()
try:
# 参考https://greasyfork.org/zh-CN/scripts/292-my-novel-reader
next_reg = r'(<a\s+.*?>.*[第上前下后][一]?[0-9]{0,6}?[页张个篇章节步].*?</a>)'
judge_reg = r'[第上前下后][一]?[0-9]{0,6}?[页张个篇章节步]'
# 这里同样需要利用bs再次解析
next_res = re.findall(next_reg, html.replace('<<', '').replace('>>', ''), re.I)
str_next_res = '\n'.join(next_res)
next_res_soup = BeautifulSoup(str_next_res, 'html5lib')
for link in next_res_soup.find_all('a'):
text = link.text or ''
text = text.replace(' ', '')
if novels_list(text):
is_next = re.search(judge_reg, text)
# is_ok = is_chapter(text)
if is_next:
url = urljoin(chapter_url, link.get('href')) or ''
regex = re.compile("^http://|^https://")
if regex.sub('', chapter_url) == regex.sub('', url):
url = False
next_chapter[text[:5]] = url
# nextDic = [{v[0]: v[1]} for v in sorted(next_chapter.items(), key=lambda d: d[1])]
return next_chapter
except Exception as e:
LOGGER.exception(e)
return next_chapter
def novels_list(text):
rm_list = ['后一个', '天上掉下个']
for i in rm_list:
if i in text:
return False
else:
continue
return True

View File

@ -0,0 +1,121 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
import os
import random
import time
import aiofiles
import aiohttp
import arrow
import async_timeout
import cchardet
import requests
from urllib.parse import urlparse
from soulbook.config import LOGGER, CONFIG
from soulbook.fetcher.novels_factory.ssl_factory import ssl_gen
async def _get_data(filename, default='') -> list:
"""
Get data from a file
:param filename: filename
:param default: default value
:return: data
"""
root_folder = os.path.dirname(os.path.dirname(__file__))
user_agents_file = os.path.join(
os.path.join(root_folder, 'data'), filename)
try:
async with aiofiles.open(user_agents_file, mode='r') as f:
data = [_.strip() for _ in await
f.readlines()]
except:
data = [default]
return data
async def get_random_user_agent() -> str:
"""
Get a random user agent string.
:return: Random user agent string.
"""
return random.choice(await _get_data('user_agents.txt', CONFIG.USER_AGENT))
def get_time() -> str:
utc = arrow.utcnow()
local = utc.to(CONFIG.TIMEZONE)
time = local.format("YYYY-MM-DD HH:mm:ss")
return time
def get_timestamp() -> float:
return time.time()
def get_netloc(url):
"""
获取netloc
:param url:
:return: netloc
"""
netloc = urlparse(url).netloc
return netloc or None
def get_scheme(url):
"""
获取scheme
:param url:
:return: scheme
"""
netloc = urlparse(url).scheme
return netloc or None
async def target_fetch(url, headers, timeout=15):
"""
:param url: target url
:return: text
"""
async with async_timeout.timeout(timeout):
try:
async with aiohttp.ClientSession() as client:
# async with client.get(url, headers=headers) as response:
async with client.get(url, headers=headers, ssl=ssl_gen()) as response:
assert response.status == 200
LOGGER.info('Task url: {}'.format(response.url))
try:
text = await response.text()
except:
try:
text = await response.read()
except aiohttp.ServerDisconnectedError as e:
LOGGER.exception(e)
text = None
return text
except Exception as e:
LOGGER.exception(str(e))
return None
def get_html_by_requests(url, headers, timeout=15):
"""
:param url:
:return:
"""
try:
response = requests.get(url=url, headers=headers, verify=False, timeout=timeout)
response.raise_for_status()
content = response.content
charset = cchardet.detect(content)
text = content.decode(charset['encoding'])
return text
except Exception as e:
LOGGER.exception(e)
return None

View File

@ -0,0 +1,4 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""

View File

@ -0,0 +1,117 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
import aiohttp
import asyncio
import async_timeout
from aiocache.serializers import PickleSerializer
from bs4 import BeautifulSoup
from urllib.parse import urlparse
from soulbook.fetcher.decorators import cached
from soulbook.fetcher.function import get_random_user_agent
from soulbook.fetcher.novels_factory.base_novels import BaseNovels
class BaiduNovels(BaseNovels):
def __init__(self):
super(BaiduNovels, self).__init__()
async def data_extraction(self, html):
"""
小说信息抓取函数
:return:
"""
try:
url = html.select('h3.t a')[0].get('href', None)
real_url = await self.get_real_url(url=url) if url else None
if real_url:
real_str_url = str(real_url)
netloc = urlparse(real_str_url).netloc
if "http://" + netloc + "/" == real_str_url:
return None
if 'baidu' in real_str_url or netloc in self.black_domain:
return None
is_parse = 1 if netloc in self.rules.keys() else 0
title = html.select('h3.t a')[0].get_text()
is_recommend = 1 if netloc in self.latest_rules.keys() else 0
# time = re.findall(r'\d+-\d+-\d+', source)
# time = time[0] if time else None
timestamp = 0
time = ""
return {'title': title, 'url': real_str_url.replace('index.html', ''), 'time': time,
'is_parse': is_parse,
'is_recommend': is_recommend,
'timestamp': timestamp,
'netloc': netloc}
else:
return None
except Exception as e:
self.logger.exception(e)
return None
async def get_real_url(self, url):
"""
获取百度搜索结果真实url
:param url:
:return:
"""
with async_timeout.timeout(5):
try:
async with aiohttp.ClientSession() as client:
headers = {'user-agent': await get_random_user_agent()}
async with client.head(url, headers=headers, allow_redirects=True) as response:
self.logger.info('Parse url: {}'.format(response.url))
url = response.url if response.url else None
return url
except Exception as e:
self.logger.exception(e)
return None
async def novels_search(self, novels_name):
"""
小说搜索入口函数
:return:
"""
url = self.config.URL_PC
params = {'wd': novels_name, 'ie': 'utf-8', 'rn': self.config.BAIDU_RN, 'vf_bl': 1}
headers = {'user-agent': await get_random_user_agent()}
html = await self.fetch_url(url=url, params=params, headers=headers)
if html:
soup = BeautifulSoup(html, 'html5lib')
result = soup.find_all(class_='result')
extra_tasks = [self.data_extraction(html=i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
done_list, pending_list = await asyncio.wait(tasks)
res = [task.result() for task in done_list if task.result()]
return res
else:
return []
@cached(ttl=259200, key_from_attr='novels_name', serializer=PickleSerializer(), namespace="novels_name")
async def start(novels_name):
"""
Start spider
:return:
"""
return await BaiduNovels.start(novels_name)
if __name__ == '__main__':
# Start
import aiocache
REDIS_DICT = {}
aiocache.settings.set_defaults(
class_="aiocache.RedisCache",
endpoint=REDIS_DICT.get('REDIS_ENDPOINT', 'localhost'),
port=REDIS_DICT.get('REDIS_PORT', 6379),
db=REDIS_DICT.get('CACHE_DB', 0),
password=REDIS_DICT.get('REDIS_PASSWORD', None),
)
res = asyncio.get_event_loop().run_until_complete(start('intitle:雪中悍刀行 小说 阅读'))
print(res)

View File

@ -0,0 +1,67 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
import aiohttp
import async_timeout
from soulbook.config import CONFIG, LOGGER, BLACK_DOMAIN, RULES, LATEST_RULES
from soulbook.fetcher.novels_factory.ssl_factory import ssl_gen
class BaseNovels:
"""
小说抓取父类
"""
def __init__(self, logger=None):
self.black_domain = BLACK_DOMAIN
self.config = CONFIG
self.latest_rules = LATEST_RULES
self.logger = logger if logger else LOGGER
self.rules = RULES
async def fetch_url(self, url, params, headers):
"""
公共抓取函数
:param client:
:param url:
:param params:
:return:
"""
async with async_timeout.timeout(15):
try:
async with aiohttp.ClientSession() as client:
print("headers: ", headers)
# async with client.get(url, params=params, headers=headers) as response:
async with client.get(url, params=params, headers=headers, ssl=ssl_gen()) as \
response:
assert response.status == 200
LOGGER.info('[fetch] Task url: {}'.format(response.url))
try:
text = await response.text()
except:
text = await response.read()
return text
except Exception as e:
LOGGER.exception(e)
return None
@classmethod
async def start(cls, novels_name):
return await cls().novels_search(novels_name)
async def data_extraction(self, html):
"""
小说信息抓取函数
:return:
"""
raise NotImplementedError
async def novels_search(self, novels_name):
"""
小说搜索入口函数
:return:
"""
raise NotImplementedError

View File

@ -0,0 +1,95 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
import asyncio
from aiocache.serializers import PickleSerializer
from bs4 import BeautifulSoup
from urllib.parse import urlparse
from soulbook.fetcher.decorators import cached
from soulbook.fetcher.function import get_random_user_agent
from soulbook.fetcher.novels_factory.base_novels import BaseNovels
class BingNovels(BaseNovels):
def __init__(self):
super(BingNovels, self).__init__()
async def data_extraction(self, html):
"""
小说信息抓取函数
:return:
"""
try:
title = html.select('h2 a')[0].get_text()
url = html.select('h2 a')[0].get('href', None)
netloc = urlparse(url).netloc
url = url.replace('index.html', '').replace('Index.html', '')
# if not url or 'baidu' in url or 'baike.so.com' in url or netloc in self.black_domain or '.html' in url:
# return None
is_parse = 1 if netloc in self.rules.keys() else 0
is_recommend = 1 if netloc in self.latest_rules.keys() else 0
timestamp = 0
time = ''
return {'title': title,
'url': url,
'time': time,
'is_parse': is_parse,
'is_recommend': is_recommend,
'timestamp': timestamp,
'netloc': netloc}
except Exception as e:
self.logger.exception(e)
return None
async def novels_search(self, novels_name):
"""
小说搜索入口函数
:return:
"""
url = self.config.BY_URL
headers = {
'user-agent': await get_random_user_agent(),
'referer': "https://www.bing.com/"
}
params = {'q': novels_name, 'ensearch': 0, "sc": "1-20"}
html = await self.fetch_url(url=url, params=params, headers=headers)
if html:
soup = BeautifulSoup(html, 'html5lib')
result = soup.find_all(class_='b_algo')
extra_tasks = [self.data_extraction(html=i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
done_list, pending_list = await asyncio.wait(tasks)
res = [task.result() for task in done_list if task.result()]
return res
else:
return []
@cached(ttl=259200, key_from_attr='novels_name', serializer=PickleSerializer(), namespace="novels_name")
async def start(novels_name):
"""
Start spider
:return:
"""
return await BingNovels.start(novels_name)
if __name__ == '__main__':
# Start
import aiocache
REDIS_DICT = {}
aiocache.settings.set_defaults(
class_="aiocache.RedisCache",
endpoint=REDIS_DICT.get('REDIS_ENDPOINT', 'localhost'),
port=REDIS_DICT.get('REDIS_PORT', 6379),
db=REDIS_DICT.get('CACHE_DB', 0),
password=REDIS_DICT.get('REDIS_PASSWORD', None),
)
res = asyncio.get_event_loop().run_until_complete(start('雪中悍刀行 小说 阅读 最新章节'))
print(res)

View File

@ -0,0 +1,89 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
import asyncio
from aiocache.serializers import PickleSerializer
from bs4 import BeautifulSoup
from urllib.parse import parse_qs, urlparse
from soulbook.fetcher.decorators import cached
from soulbook.fetcher.function import get_random_user_agent
from soulbook.fetcher.novels_factory.base_novels import BaseNovels
class DuckGoNovels(BaseNovels):
def __init__(self):
super(DuckGoNovels, self).__init__()
async def data_extraction(self, html):
"""
小说信息抓取函数
:return:
"""
try:
title = html.select('h2 a')[0].get_text()
url = html.select('h2 a')[0].get('href', None)
url = parse_qs(url).get('uddg', ['#'])[0]
netloc = urlparse(url).netloc
url = url.replace('index.html', '').replace('Index.html', '')
if not url or 'baidu' in url or 'baike.so.com' in url or netloc in self.black_domain or '.html' in url:
return None
is_parse = 1 if netloc in self.rules.keys() else 0
is_recommend = 1 if netloc in self.latest_rules.keys() else 0
# time = html.select('div.b_attribution')[0].get_text()
# time = re.findall(r'\d+-\d+-\d+', time)
# time = time[0] if time else ''
timestamp = 0
time = ''
return {'title': title,
'url': url,
'time': time,
'is_parse': is_parse,
'is_recommend': is_recommend,
'timestamp': timestamp,
'netloc': netloc}
except Exception as e:
self.logger.exception(e)
return None
async def novels_search(self, novels_name):
"""
小说搜索入口函数
:return:
"""
url = self.config.DUCKGO_URL
headers = {
'user-agent': await get_random_user_agent(),
'referer': "https://duckduckgo.com/"
}
params = {'q': novels_name}
html = await self.fetch_url(url=url, params=params, headers=headers)
if html:
soup = BeautifulSoup(html, 'html5lib')
result = soup.find_all(class_='result')
extra_tasks = [self.data_extraction(html=i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
done_list, pending_list = await asyncio.wait(tasks)
res = [task.result() for task in done_list if task.result()]
return res
else:
return []
@cached(ttl=259200, key_from_attr='novels_name', serializer=PickleSerializer(), namespace="novels_name")
async def start(novels_name):
"""
Start spider
:return:
"""
return await DuckGoNovels.start(novels_name)
if __name__ == '__main__':
# Start
res = asyncio.get_event_loop().run_until_complete(start('雪中悍刀行 小说 阅读 最新章节'))
print(res)

View File

@ -0,0 +1,105 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
import asyncio
from aiocache.serializers import PickleSerializer
from bs4 import BeautifulSoup
from urllib.parse import parse_qs, urlparse
from soulbook.fetcher.decorators import cached
from soulbook.fetcher.function import get_random_user_agent
from soulbook.fetcher.novels_factory.base_novels import BaseNovels
class SoNovels(BaseNovels):
def __init__(self):
super(SoNovels, self).__init__()
async def data_extraction(self, html):
"""
小说信息抓取函数
:return:
"""
try:
# 2017.09.09 修改 更加全面地获取title && url
try:
title = html.select('h3 a')[0].get_text()
url = html.select('h3 a')[0].get('href', None)
except Exception as e:
self.logger.exception(e)
return None
# 针对不同的请进行url的提取
if "www.so.com/link?m=" in url:
url = html.select('h3 a')[0].get('data-mdurl', None)
if "www.so.com/link?url=" in url:
url = parse_qs(urlparse(url).query).get('url', None)
url = url[0] if url else None
netloc = urlparse(url).netloc
if not url or 'baidu' in url or 'baike.so.com' in url or netloc in self.black_domain:
return None
is_parse = 1 if netloc in self.rules.keys() else 0
is_recommend = 1 if netloc in self.latest_rules.keys() else 0
time = ''
timestamp = 0
return {'title': title, 'url': url.replace('index.html', '').replace('Index.html', ''), 'time': time,
'is_parse': is_parse,
'is_recommend': is_recommend,
'timestamp': timestamp,
'netloc': netloc}
except Exception as e:
self.logger.exception(e)
return None
async def novels_search(self, novels_name):
"""
小说搜索入口函数
:return:
"""
url = self.config.SO_URL
headers = {
'User-Agent': await get_random_user_agent(),
'Referer': "http://www.so.com/haosou.html?src=home"
}
params = {'ie': 'utf-8', 'src': 'noscript_home', 'shb': 1, 'q': novels_name, }
html = await self.fetch_url(url=url, params=params, headers=headers)
if html:
soup = BeautifulSoup(html, 'html5lib')
result = soup.find_all(class_='res-list')
extra_tasks = [self.data_extraction(html=i) for i in result]
tasks = [asyncio.ensure_future(i) for i in extra_tasks]
done_list, pending_list = await asyncio.wait(tasks)
res = [task.result() for task in done_list if task.result()]
return res
else:
return []
@cached(ttl=259200, key_from_attr='novels_name', serializer=PickleSerializer(), namespace="novels_name")
async def start(novels_name):
"""
Start spider
:return:
"""
return await SoNovels.start(novels_name)
if __name__ == '__main__':
# Start
import aiocache
REDIS_DICT = {}
aiocache.settings.set_defaults(
class_="aiocache.RedisCache",
endpoint=REDIS_DICT.get('REDIS_ENDPOINT', 'localhost'),
port=REDIS_DICT.get('REDIS_PORT', 6379),
db=REDIS_DICT.get('CACHE_DB', 0),
password=REDIS_DICT.get('REDIS_PASSWORD', None),
)
res = asyncio.get_event_loop().run_until_complete(start('雪中悍刀行 小说 最新章节'))
print(res)

View File

@ -0,0 +1,31 @@
# coding: utf-8
"""
绕过 JA3指纹反爬机制
参考https://mp.weixin.qq.com/s/tuZScT0qVwPl6bQewqz0zg
"""
import random
import ssl
# ssl._create_default_https_context = ssl._create_unverified_context
ORIGIN_CIPHERS = ('ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES')
class SSLFactory:
def __init__(self):
self.ciphers = ORIGIN_CIPHERS.split(":")
def __call__(self) -> ssl.SSLContext:
random.shuffle(self.ciphers)
ciphers = ":".join(self.ciphers)
ciphers = ciphers + ":!aNULL:!eNULL:!MD5"
context = ssl.create_default_context()
context.set_ciphers(ciphers)
return context
ssl_gen = SSLFactory()

View File

@ -0,0 +1,33 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
import asyncio
import os
import schedule
import sys
import time
import uvloop
os.environ['MODE'] = 'PRO'
sys.path.append('../../')
from soulbook.fetcher.cache import update_all_books
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
loop = asyncio.get_event_loop()
def update_all_books_schedule():
task = asyncio.ensure_future(update_all_books(loop))
loop.run_until_complete(task)
return task.result() or None
# python novels_schedule.py
schedule.every(180).minutes.do(update_all_books_schedule)
while True:
schedule.run_pending()
time.sleep(1)

View File

@ -0,0 +1,36 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/5/28.
"""
from importlib import import_module
async def get_novels_info(class_name, novels_name):
novels_module = import_module(
"soulbook.fetcher.{}.{}_novels".format('novels_factory', class_name))
try:
# 获取对应渠道实例化对象
novels_info = await novels_module.start(novels_name)
except Exception as e:
print("get_novels_info: %s" % e)
novels_info = None
return novels_info
if __name__ == '__main__':
import asyncio
import aiocache
REDIS_DICT = {}
aiocache.settings.set_defaults(
class_="aiocache.RedisCache",
endpoint=REDIS_DICT.get('REDIS_ENDPOINT', 'localhost'),
port=REDIS_DICT.get('REDIS_PORT', 6379),
db=REDIS_DICT.get('CACHE_DB', 0),
password=REDIS_DICT.get('REDIS_PASSWORD', None),
)
res = asyncio.get_event_loop().run_until_complete(
get_novels_info(class_name='baidu', novels_name='intitle:雪中悍刀行 小说 阅读'))
print(res)

View File

@ -0,0 +1,64 @@
#!/usr/bin/env python
"""
Created by howie.hu at 17-9-22.
"""
class ResponseField():
"""
Define the response field
"""
MESSAGE = 'info'
STATUS = 'state'
DATA = 'data'
FINISH_AT = 'finished_at'
class ResponseReply():
"""
Define field description
"""
# ERROR
UNKNOWN_ERR = '未知错误'
PARAM_ERR = '参数错误!'
PARAM_PARSE_ERR = "参数解析错误!"
DB_ERROR = "数据库操作错误"
# FORBIDDEN
IP_FORBIDDEN = "ip被禁"
# NOT AUTHORIZED
NOT_AUTHORIZED = "验证未通过"
# SUCCESS
SUCCESS = 'ok'
class ResponseCode():
"""
Define the response code
"""
SUCCESS = 200
CREATED = 201
NO_CONTENT = 204
BAD_REQUEST = 400
NOT_AUTHORIZED = 401
FORBIDDEN = 403
NOT_FOUND = 404
SERVER_ERR = 500
class UniResponse():
NOT_AUTHORIZED = {ResponseField.MESSAGE: ResponseReply.NOT_AUTHORIZED,
ResponseField.STATUS: ResponseCode.NOT_AUTHORIZED}
PARAM_PARSE_ERR = {ResponseField.MESSAGE: ResponseReply.PARAM_PARSE_ERR,
ResponseField.STATUS: ResponseCode.BAD_REQUEST}
PARAM_ERR = {ResponseField.MESSAGE: ResponseReply.PARAM_ERR,
ResponseField.STATUS: ResponseCode.BAD_REQUEST}
PARAM_UNKNOWN_ERR = {ResponseField.MESSAGE: ResponseReply.UNKNOWN_ERR,
ResponseField.STATUS: ResponseCode.BAD_REQUEST}
IP_FORBIDDEN = {ResponseField.MESSAGE: ResponseReply.IP_FORBIDDEN,
ResponseField.STATUS: ResponseCode.FORBIDDEN}
SERVER_DB_ERR = {ResponseField.MESSAGE: ResponseReply.DB_ERROR,
ResponseField.STATUS: ResponseCode.SERVER_ERR}
SERVER_UNKNOWN_ERR = {ResponseField.MESSAGE: ResponseReply.UNKNOWN_ERR,
ResponseField.STATUS: ResponseCode.SERVER_ERR}
SUCCESS = {ResponseField.MESSAGE: ResponseReply.SUCCESS,
ResponseField.STATUS: ResponseCode.SUCCESS}

View File

@ -0,0 +1 @@
from .cosinesimilarity import CosineSimilarity

View File

@ -0,0 +1,58 @@
import numpy as np
from functools import reduce
from math import sqrt
class CosineSimilarity(object):
"""
余弦相似性计算相似度
"""
def __init__(self, initQuery, userData):
self.title = initQuery
self.data = userData
def create_vector(self):
"""
创建兴趣向量
:return: wordVector = {} 目标用户以及各个兴趣对应的向量
"""
wordVector = {}
for web, value in self.data.items():
wordVector[web] = []
titleVector, valueVector = [], []
allWord = set(self.title + value)
for eachWord in allWord:
titleNum = self.title.count(eachWord)
valueNum = value.count(eachWord)
titleVector.append(titleNum)
valueVector.append(valueNum)
wordVector[web].append(titleVector)
wordVector[web].append(valueVector)
return wordVector
def calculate(self, wordVector):
"""
计算余弦相似度
:param wordVector: wordVector = {} 目标用户以及各个兴趣对应的向量
:return: 返回各个用户相似度值
"""
resultDic = {}
for web, value in wordVector.items():
valueArr = np.array(value)
# 余弦相似性
squares = []
numerator = reduce(lambda x, y: x + y, valueArr[0] * valueArr[1])
square_title, square_data = 0.0, 0.0
for num in range(len(valueArr[0])):
square_title += pow(valueArr[0][num], 2)
square_data += pow(valueArr[1][num], 2)
squares.append(sqrt(square_title))
squares.append(sqrt(square_data))
mul_of_squares = reduce(lambda x, y: x * y, squares)
value = float(('%.5f' % (numerator / mul_of_squares)))
if value > 0:
resultDic[web] = value
resultDic = [{v[0]: v[1]} for v in sorted(resultDic.items(), key=lambda d: d[1], reverse=True)]
return resultDic

View File

@ -0,0 +1 @@
#!/usr/bin/env python

22
soulbook/run.py Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/8/13.
"""
import os
import subprocess
if __name__ == '__main__':
os.environ['MODE'] = 'PRO'
servers = [
["pipenv", "run", "gunicorn", "-c", "config/gunicorn.py", "--worker-class", "sanic.worker.GunicornWorker",
"server:app"],
["pipenv", "run", "python", "scheduled_task.py"]
]
procs = []
for server in servers:
proc = subprocess.Popen(server)
procs.append(proc)
for proc in procs:
proc.wait()
if proc.poll():
exit(0)

View File

@ -0,0 +1,47 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/8/13.
"""
import os
import asyncio
import sys
import time
import schedule
import uvloop
os.environ['MODE'] = 'PRO'
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from soulbook.config import CONFIG
from soulbook.spiders import QidianRankingSpider, ZHRankingSpider
from soulbook.fetcher.cache import update_all_books
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
loop = asyncio.get_event_loop()
def start_spider():
QidianRankingSpider.start()
ZHRankingSpider.start()
def update_all_books_schedule():
task = asyncio.ensure_future(update_all_books(loop))
loop.run_until_complete(task)
return task.result() or None
def refresh_task():
schedule.every(CONFIG.SCHEDULED_DICT['SPIDER_INTERVAL']).minutes.do(start_spider)
# schedule.every(CONFIG.SCHEDULED_DICT['NOVELS_INTERVAL']).minutes.do(update_all_books_schedule)
while True:
schedule.run_pending()
time.sleep(1)
if __name__ == '__main__':
start_spider()
refresh_task()

88
soulbook/server.py Normal file
View File

@ -0,0 +1,88 @@
#!/usr/bin/env python
import aiocache
import os
import sys
from sanic import Sanic
from sanic.response import html, redirect
from sanic_session import RedisSessionInterface
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from soulbook.views import admin_bp, api_bp, except_bp, md_bp, novels_bp, operate_bp
from soulbook.database.redis import RedisSession
from soulbook.config import LOGGER, CONFIG
app = Sanic(__name__)
app.blueprint(md_bp)
app.blueprint(novels_bp)
app.blueprint(operate_bp)
app.blueprint(except_bp)
app.blueprint(admin_bp)
app.blueprint(api_bp)
@app.listener('before_server_start')
def init_cache(app, loop):
LOGGER.info("Starting aiocache")
app.config.from_object(CONFIG)
REDIS_DICT = CONFIG.REDIS_DICT
aiocache.settings.set_defaults(
class_="aiocache.RedisCache",
endpoint=REDIS_DICT.get('REDIS_ENDPOINT', 'localhost'),
port=REDIS_DICT.get('REDIS_PORT', 6379),
db=REDIS_DICT.get('CACHE_DB', 0),
password=REDIS_DICT.get('REDIS_PASSWORD', None),
loop=loop,
)
LOGGER.info("Starting redis pool")
redis_session = RedisSession()
# redis instance for app
app.get_redis_pool = redis_session.get_redis_pool
# pass the getter method for the connection pool into the session
app.session_interface = RedisSessionInterface(
app.get_redis_pool, cookie_name="owl_sid", expiry=30 * 24 * 60 * 60)
@app.middleware('request')
async def add_session_to_request(request):
# before each request initialize a session
# using the client's request
host = request.headers.get('host', None)
user_agent = request.headers.get('user-agent', None)
if user_agent:
user_ip = request.headers.get('X-Forwarded-For')
LOGGER.info('user ip is: {}'.format(user_ip))
if user_ip in CONFIG.FORBIDDEN:
return html("<h3>网站正在维护...</h3>")
if CONFIG.VAL_HOST == 'true':
if not host or host not in CONFIG.HOST:
return redirect('http://www.owllook.net')
if CONFIG.WEBSITE['IS_RUNNING']:
await app.session_interface.open(request)
else:
return html("<h3>网站正在维护...</h3>")
else:
return html("<h3>网站正在维护...</h3>")
@app.middleware('response')
async def save_session(request, response):
# after each request save the session,
# pass the response to set client cookies
# await app.session_interface.save(request, response)
if request.path == '/operate/login' and request['session'].get('user', None):
await app.session_interface.save(request, response)
import datetime
response.cookies['owl_sid']['expires'] = datetime.datetime.now(
) + datetime.timedelta(days=30)
elif request.path == '/register':
try:
response.cookies['reg_index'] = str(request['session']['index'][0])
except KeyError as e:
LOGGER.error(e)
if __name__ == "__main__":
workers = 1 if os.name == 'nt' else 2
app.run(host="0.0.0.0", workers=workers, port=8001, debug=CONFIG.DEBUG)

View File

@ -0,0 +1,24 @@
## 小说榜单爬虫
> 获取各大小说站的小说榜单排名,使用自己写的简单爬虫框架[talospider](https://github.com/howie6879/talospider)来进行脚本的编写
### 1.起点榜单
> 网址http://r.qidian.com/?chn=-1
| 参数 | 说明 |
| :-------------------------: | :--: |
| http://r.qidian.com/?chn=-1 | 全部分类 |
| http://r.qidian.com/?chn=21 | 玄幻 |
| http://r.qidian.com/?chn=1 | 奇幻 |
| http://r.qidian.com/?chn=2 | 武侠 |
| http://r.qidian.com/?chn=22 | 仙侠 |
| http://r.qidian.com/?chn=4 | 都市 |
| http://r.qidian.com/?chn=15 | 职场 |
| http://r.qidian.com/?chn=6 | 军事 |
| http://r.qidian.com/?chn=5 | 历史 |
| http://r.qidian.com/?chn=7 | 游戏 |
| http://r.qidian.com/?chn=8 | 体育 |
| http://r.qidian.com/?chn=9 | 科幻 |
| http://r.qidian.com/?chn=10 | 灵异 |
| http://r.qidian.com/?chn=12 | 二次元 |

View File

@ -0,0 +1,2 @@
from .qidian_ranking import QidianRankingSpider
from .zh_ranking import ZHRankingSpider

View File

@ -0,0 +1,102 @@
#!/usr/bin/env python
"""
Created by howie.hu at 30/03/2018.
"""
import time
from pprint import pprint
from ruia import Spider, Item, TextField, AttrField
from ruia_ua import middleware as ua_middleware
from soulbook.database.mongodb import MotorBase
class HYNovelInfoItem(Item):
"""
定义继承自item的Item类
"""
novel_name = AttrField(css_select="meta[property='og:title']", attr='content')
author = AttrField(css_select="meta[property='og:novel:author']", attr='content')
cover = AttrField(css_select="meta[property='og:image']", attr='content')
abstract = AttrField(css_select="meta[property='og:description']", attr='content')
status = AttrField(css_select="meta[property='og:novel:status']", attr='content')
novels_type = AttrField(css_select="meta[property='og:novel:category']", attr='content')
novel_chapter_url = AttrField(css_select='div#voteList a.index', attr='href')
latest_chapter = AttrField(css_select="meta[property='og:novel:latest_chapter_name']", attr='content')
latest_chapter_url = AttrField(css_select="meta[property='og:novel:latest_chapter_url']", attr='content')
latest_chapter_time = AttrField(css_select="meta[property='og:novel:update_time']", attr='content')
# novel_name = TextField(css_select='div.c-left>div.mod>div.hd>h2')
# author = TextField(css_select='div.author-zone div.right a.name strong')
# cover = AttrField(css_select='img.book-cover', attr='src')
# abstract = TextField(css_select='pre.note')
# status = ''
# novels_type = TextField(css_select='div.c-left>div.mod>div.hd>p.infos>span.cate>a')
# latest_chapter = ''
# novel_chapter_url = AttrField(css_select='div#voteList a.index', attr='href')
async def clean_cover(self, cover):
if 'https' in cover:
return cover
else:
return cover.replace('http', 'https')
async def clean_novels_type(self, novels_type):
types_dict = {
'社会': '都市'
}
print(types_dict.get(str(novels_type).strip(), novels_type))
return types_dict.get(str(novels_type).strip(), novels_type)
async def clean_latest_chapter_time(self, latest_chapter_time):
return latest_chapter_time.replace(u'今天', str(time.strftime("%Y-%m-%d ", time.localtime()))).replace(u'昨日', str(
time.strftime("%Y-%m-%d ", time.localtime(time.time() - 24 * 60 * 60))))
class HYNovelInfoSpider(Spider):
start_urls = []
request_config = {
'RETRIES': 3,
'TIMEOUT': 10
}
async def parse(self, res):
self.motor_db = MotorBase(loop=self.loop).get_db()
item = await HYNovelInfoItem.get_item(html=res.html)
item_data = {
'novel_name': item.novel_name,
'author': item.author,
'cover': item.cover,
'abstract': item.abstract,
'status': item.status,
'novels_type': item.novels_type,
'novel_chapter_url': item.novel_chapter_url,
'latest_chapter': item.latest_chapter,
'latest_chapter_time': item.latest_chapter_time,
'spider': 'heiyan',
'target_url': res.url,
'updated_at': time.strftime("%Y-%m-%d %X", time.localtime())
}
print('获取 {} 小说信息成功'.format(item_data['novel_name']))
await self.save(res_dic=item_data)
async def save(self, res_dic):
# 存进数据库
try:
motor_db = MotorBase().get_db()
await motor_db.all_novels_info.update_one({
'novel_name': res_dic['novel_name'], 'spider': 'heiyan'},
{'$set': res_dic},
upsert=True)
except Exception as e:
self.logger.exception(e)
if __name__ == '__main__':
HYNovelInfoSpider.start_urls = ['http://www.heiyan.com/book/62599']
# HYNovelInfoSpider.start_urls = [each.get('novel_url', '') for each in search_author('火星引力', 'qidian')]
print(HYNovelInfoSpider.start_urls)
HYNovelInfoSpider.start(middleware=ua_middleware)

View File

@ -0,0 +1,31 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/10/17.
"""
from ruia import Middleware
from soulbook.spiders.spider_tools import get_proxy_ip
owl_middleware = Middleware()
@owl_middleware.request
async def add_random_proxy(request):
request.kwargs.update({'proxy': await update_proxy()})
request.request_config.update({'RETRY_FUNC': retry_func})
async def update_proxy():
proxy = await get_proxy_ip()
if proxy:
proxy = 'http://' + proxy
else:
proxy = None
return proxy
async def retry_func(request):
proxy = await update_proxy()
request.kwargs.update({'proxy': proxy})
return request

View File

@ -0,0 +1,120 @@
#!/usr/bin/env python
"""
Created by howie.hu at 25/02/2018.
Target URI: https://www.qidian.com/all
Param:?page=1
"""
import asyncio
import os
import time
from ruia import Spider, Item, TextField, AttrField
from ruia_ua import middleware as ua_middleware
# os.environ['MODE'] = 'PRO'
from soulbook.database.mongodb import MotorBase
from soulbook.spiders.middlewares import owl_middleware
try:
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
pass
loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
class QidianNovelsItem(Item):
target_item = TextField(css_select='ul.all-img-list>li')
novel_url = AttrField(css_select='div.book-img-box>a', attr='href')
novel_name = TextField(css_select='div.book-mid-info>h4')
novel_author = TextField(css_select='div.book-mid-info>p.author>a.name')
novel_author_home_url = AttrField(css_select='div.book-mid-info>p.author>a.name', attr='href')
novel_type = TextField(css_select='div.book-mid-info > p.author > a:nth-child(4)')
novel_cover = AttrField(css_select='div.book-img-box img', attr='src')
novel_abstract = TextField(css_select='div.book-mid-info p.intro')
# novel_latest_chapter = TextField(css_select='div.bookupdate a')
async def clean_novel_url(self, novel_url):
return 'https:' + novel_url
async def clean_novel_author(self, novel_author):
if isinstance(novel_author, list):
novel_author = novel_author[0].text
return novel_author
async def clean_novel_author_home_url(self, novel_author_home_url):
if isinstance(novel_author_home_url, list):
novel_author_home_url = novel_author_home_url[0].get('href').strip()
return 'https:' + novel_author_home_url
async def clean_novel_cover(self, novel_cover):
return 'https:' + novel_cover
class QidianNovelsSpider(Spider):
# start_urls = ['https://www.qidian.com/all?page=1']
request_config = {
'RETRIES': 15,
'DELAY': 0,
'TIMEOUT': 3
}
concurrency = 20
motor_db = MotorBase(loop=loop).get_db()
async def parse(self, res):
items_data = await QidianNovelsItem.get_items(html=res.html)
tasks = []
for item in items_data:
res_dic = {
'novel_url': item.novel_url,
'novel_name': item.novel_name,
'novel_author': item.novel_author,
'novel_author_home_url': item.novel_author_home_url,
'novel_type': item.novel_type,
'novel_cover': item.novel_cover,
'novel_abstract': item.novel_abstract,
'spider': 'qidian',
'updated_at': time.strftime("%Y-%m-%d %X", time.localtime()),
}
tasks.append(asyncio.ensure_future(self.save(res_dic)))
good_nums = 0
if tasks:
done_list, pending_list = await asyncio.wait(tasks)
for task in done_list:
if task.result():
good_nums += 1
print(f"{len(tasks)}本小说,抓取成功{good_nums}")
async def save(self, res_dic):
# 存进数据库
try:
await self.motor_db.all_novels.update_one(
{'novel_url': res_dic['novel_url'], 'novel_name': res_dic['novel_name']},
{'$set': res_dic},
upsert=True)
print(res_dic['novel_name'] + ' - 抓取成功')
return True
except Exception as e:
self.logger.exception(e)
return False
if __name__ == '__main__':
# 51793
for page in range(248, 519):
print(f"正在爬取第{page}")
start_page = page * 100
end_page = start_page + 100
if end_page > 51793:
end_page = 51793
QidianNovelsSpider.start_urls = ['https://www.qidian.com/all?page={i}'.format(i=i) for i in
range(start_page, end_page)]
# 其他多item示例https://gist.github.com/howie6879/3ef4168159e5047d42d86cb7fb706a2f
QidianNovelsSpider.start(loop=loop, middleware=[ua_middleware, owl_middleware], close_event_loop=False)

View File

@ -0,0 +1,64 @@
#!/usr/bin/env python
"""
Created by howie.hu at 11/03/2018.
获取起点荣誉数据https://book.qidian.com/honor/1009704712
荣誉类型
- 推荐票
- 收藏
- 点击
"""
from ruia import Spider, Item, TextField
from ruia_ua import middleware
class QidianHonorItem(Item):
target_item = TextField(css_select='li.cf')
honor_text = TextField(css_select='span.decs')
honor_time = TextField(css_select='span.time')
class QidianHonorSpider(Spider):
start_urls = ['https://book.qidian.com/honor/1009531496']
request_config = {
'RETRIES': 3,
'DELAY': 0,
'TIMEOUT': 10
}
async def parse(self, res):
items_data = await QidianHonorItem.get_items(html=res.html)
click_list, col_list, rec_list, other_list = [], [], [], []
for item in items_data:
data = {
'honor_text': item.honor_text,
'honor_time': item.honor_time,
}
if "点击" in data['honor_text'] and '月点击' not in data['honor_text']:
click_list.append(data)
elif "收藏" in data['honor_text']:
col_list.append(data)
elif "推荐票" in data['honor_text']:
rec_list.append(data)
else:
other_list.append(data)
print('点击荣誉\n')
for i in click_list:
print(str(i.get('honor_time')) + " - " + str(i.get('honor_text')))
print('收藏荣誉\n')
for i in col_list:
print(str(i.get('honor_time')) + " - " + str(i.get('honor_text')))
print('推荐票荣誉\n')
for i in rec_list:
print(str(i.get('honor_time')) + " - " + str(i.get('honor_text')))
print('强推荣誉\n')
for i in other_list:
print(str(i.get('honor_time')) + " - " + str(i.get('honor_text')))
if __name__ == '__main__':
QidianHonorSpider.start(middleware=middleware)

View File

@ -0,0 +1,85 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
import os
import time
from ruia import Spider, Item, TextField, AttrField
from ruia_ua import middleware
os.environ['MODE'] = 'PRO'
from soulbook.database.mongodb import MotorBaseOld
class QidianNovelInfoItem(Item):
"""
定义继承自item的Item类
"""
novel_name = TextField(css_select='.book-info>h1>em')
author = TextField(css_select='a.writer')
# 当提取的值是属性的时候要定义AttrField
cover = AttrField(css_select='a#bookImg>img', attr='src')
abstract = TextField(css_select='div.book-intro>p')
status = TextField(css_select='p.tag>span.blue')
novels_type = TextField(css_select='p.tag>a.red')
latest_chapter = TextField(css_select='li.update>div.detail>p.cf>a')
latest_chapter_time = TextField(css_select='div.detail>p.cf>em')
async def clean_cover(self, cover):
return 'http:' + cover
async def clean_status(self, status):
"""
当目标值的对象只有一个默认将值提取出来否则返回list可以在这里定义一个函数进行循环提取
:param ele_tag:
:return:
"""
return '#'.join([i.text for i in status])
async def clean_novels_type(self, novels_type):
return '#'.join([i.text for i in novels_type])
async def clean_latest_chapter_time(self, latest_chapter_time):
return latest_chapter_time.replace(u'今天', str(time.strftime("%Y-%m-%d ", time.localtime()))).replace(u'昨日', str(
time.strftime("%Y-%m-%d ", time.localtime(time.time() - 24 * 60 * 60))))
class QidianNovelInfoSpider(Spider):
request_config = {
'RETRIES': 3,
'TIMEOUT': 10
}
async def parse(self, res):
motor_db = MotorBaseOld().db
item = await QidianNovelInfoItem.get_item(html=res.html)
item_data = {
'novel_name': item.novel_name,
'author': item.author,
'cover': item.cover,
'abstract': item.abstract,
'status': item.status,
'novels_type': item.novels_type,
'latest_chapter': item.latest_chapter,
'latest_chapter_time': item.latest_chapter_time,
'spider': 'qidian',
'target_url': res.url,
'updated_at': time.strftime("%Y-%m-%d %X", time.localtime())
}
print('获取 {} 小说信息成功'.format(item.novel_name))
await motor_db.all_novels_info.update_one(
{'novel_name': item_data['novel_name'], 'spider': item_data['spider']},
{'$set': item_data},
upsert=True)
if __name__ == '__main__':
import random
# 其他多item示例https://gist.github.com/howie6879/3ef4168159e5047d42d86cb7fb706a2f
QidianNovelInfoSpider.start_urls = ['https://book.qidian.com/info/1004608738',
'https://book.qidian.com/info/3602691',
'https://book.qidian.com/info/3347595', 'https://book.qidian.com/info/1887208']
# QidianNovelInfoSpider.start_urls = all_urls
QidianNovelInfoSpider.start(middleware=middleware)

View File

@ -0,0 +1,98 @@
#!/usr/bin/env python
import asyncio
import time
from ruia import Spider, Item, AttrField, HtmlField, TextField
from ruia_ua import middleware
from soulbook.database.mongodb import MotorBaseOld
class RankingItem(Item):
target_item = TextField(css_select='.rank-list')
ranking_title = TextField(css_select='h3.wrap-title')
more = AttrField(css_select='h3>a.more', attr='href')
book_list = HtmlField(css_select='div.book-list>ul>li', many=True)
async def clean_ranking_title(self, ranking_title):
if isinstance(ranking_title, list):
return ranking_title[0].text
else:
return str(ranking_title).split('')[0] + ''
async def clean_more(self, more):
return "https:" + more
class NameItem(Item):
top_name = TextField(css_select='h4', default='')
other_name = TextField(css_select='a.name', default='')
class QidianRankingSpider(Spider):
start_urls = [f"https://www.qidian.com/rank/?chn={key}" for key in
[-1, 21, 1, 2, 22, 4, 15, 6, 5, 7, 8, 9, 10, 12]]
concurrency = 3
qidian_type = {
'-1': '全部类别',
'21': '玄幻',
'1': '奇幻',
'2': '武侠',
'22': '仙侠',
'4': '都市',
'15': '职场',
'6': '军事',
'5': '历史',
'7': '游戏',
'8': '体育',
'9': '科幻',
'10': '灵异',
'12': '二次元',
}
async def parse(self, res):
result = []
res_dic = {}
async for item in RankingItem.get_items(html=res.html):
each_book_list = []
# 只取排名前十的书籍数据
for index, value in enumerate(item.book_list[:10]):
item_data = await NameItem.get_item(html=value)
name = item_data.top_name or item_data.other_name
each_book_list.append({
'num': index + 1,
'name': name
})
data = {
'title': item.ranking_title,
'more': item.more,
'book_list': each_book_list,
'updated_at': time.strftime("%Y-%m-%d %X", time.localtime()),
}
result.append(data)
res_dic['data'] = result
res_dic['target_url'] = res.url
res_dic['type'] = self.qidian_type.get(res.url.split('=')[-1])
res_dic['spider'] = "qidian"
await self.save(res_dic=res_dic)
async def save(self, res_dic):
# 存进数据库
try:
motor_db = MotorBaseOld().db
await motor_db.novels_ranking.update_one({
'target_url': res_dic['target_url']},
{'$set': {
'data': res_dic['data'],
'spider': res_dic['spider'],
'type': res_dic['type'],
'finished_at': time.strftime("%Y-%m-%d %X", time.localtime())
}},
upsert=True)
except Exception as e:
self.logger.exception(e)
if __name__ == '__main__':
QidianRankingSpider.start(middleware=middleware)

View File

@ -0,0 +1,23 @@
# !/usr/bin/env python
import os
import schedule
import sys
import time
os.environ['MODE'] = 'PRO'
sys.path.append('../../')
from soulbook.spiders import QidianRankingSpider, ZHRankingSpider
def start_spider():
QidianRankingSpider.start()
ZHRankingSpider.start()
# python novels_schedule.py
schedule.every(60).minutes.do(start_spider)
while True:
schedule.run_pending()
time.sleep(1)

View File

@ -0,0 +1,35 @@
#!/usr/bin/env python
"""
Created by howie.hu at 2018/10/17.
"""
import asyncio
import random
from ruia import Request
from soulbook.config import CONFIG
async def get_proxy_ip(valid: int = 1) -> str:
# random_server = ['http://0.0.0.0:8662/']
proxy_server = CONFIG.REMOTE_SERVER.get('proxy_server')
# proxy_server = random_server[random.randint(0, 1)]
kwargs = {
'json': {
"act_id": 1704,
"version": "1.0",
"data": {
"valid": 1
}
}
}
res = await Request(url=proxy_server, method='POST', res_type='json', **kwargs).fetch()
proxy = ''
if res.status == 200:
proxy = res.html.get('info').get('proxy')
return proxy
if __name__ == '__main__':
print(asyncio.get_event_loop().run_until_complete(get_proxy_ip()))

View File

@ -0,0 +1,75 @@
#!/usr/bin/env python
"""
Created by howie.hu at 29/11/2017.
"""
import time
from ruia import Spider, Item, AttrField, HtmlField, TextField
from ruia_ua import middleware
from soulbook.database.mongodb import MotorBaseOld
class RankingItem(Item):
target_item = TextField(css_select='div.rank_i_p_list')
ranking_title = TextField(css_select='div.rank_i_p_tit')
more = AttrField(css_select='div.rank_i_more a', attr='href')
book_list = HtmlField(css_select='div.rank_i_p_list>div.rank_i_li', many=True)
class NameItem(Item):
top_name = TextField(css_select='div.rank_i_bname a.rank_i_l_a_book', default='')
other_name = TextField(css_select='div.rank_i_bname a', default='')
class ZHRankingSpider(Spider):
start_urls = ['http://book.zongheng.com/rank.html']
concurrency = 3
async def parse(self, res):
result = []
res_dic = {}
async for item in RankingItem.get_items(html=res.html):
each_book_list = []
# 只取排名前十的书籍数据
for index, value in enumerate(item.book_list[:10]):
item_data = await NameItem.get_item(html=value)
name = item_data.top_name or item_data.other_name
each_book_list.append({
'num': index + 1,
'name': name
})
data = {
'title': item.ranking_title,
'more': item.more,
'book_list': each_book_list,
'updated_at': time.strftime("%Y-%m-%d %X", time.localtime()),
}
result.append(data)
res_dic['data'] = result
res_dic['target_url'] = res.url
res_dic['type'] = "人气榜单"
res_dic['spider'] = "zongheng"
await self.save(res_dic)
async def save(self, res_dic):
try:
motor_db = MotorBaseOld().db
await motor_db.novels_ranking.update_one({
'target_url': res_dic['target_url']},
{'$set': {
'data': res_dic['data'],
'spider': res_dic['spider'],
'type': res_dic['type'],
'finished_at': time.strftime("%Y-%m-%d %X", time.localtime())
}},
upsert=True)
except Exception as e:
self.logger.exception(e)
if __name__ == '__main__':
ZHRankingSpider.start(middleware=middleware)

View File

@ -0,0 +1,127 @@
#!/usr/bin/env python
"""
Created by howie.hu at 14/03/2018.
纵横小说信息提取http://book.zongheng.com/store/c0/c0/b9/u0/p1/v9/s9/t0/ALL.html
"""
import asyncio
import os
import time
from ruia import Spider, Item, TextField, AttrField, Request
from ruia_ua import middleware as ua_middleware
# os.environ['MODE'] = 'PRO'
from soulbook.database.mongodb import MotorBase
from soulbook.spiders.middlewares import owl_middleware
try:
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
pass
loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
class ZHNovelsItem(Item):
target_item = TextField(css_select='div.store_collist div.bookbox')
novel_url = AttrField(css_select='div.bookinfo div.bookname a', attr='href')
novel_name = TextField(css_select='div.bookinfo div.bookname a')
novel_author = TextField(css_select='div.bookilnk a:nth-child(1)')
novel_author_home_url = AttrField(css_select='div.bookilnk a:nth-child(1)', attr='href')
novel_type = TextField(css_select='div.bookilnk a:nth-child(2)')
novel_cover = AttrField(css_select='div.bookimg img', attr='src')
novel_abstract = TextField(css_select='div.bookintro')
novel_latest_chapter = TextField(css_select='div.bookupdate a')
# def tal_novel_url(self, novel_url):
# return 'http:' + novel_url
async def clean_novel_author(self, novel_author):
if novel_author:
if isinstance(novel_author, list):
novel_author = novel_author[0].text
return novel_author
else:
return ''
# def tal_novel_author_home_url(self, novel_author_home_url):
# if isinstance(novel_author_home_url, list):
# novel_author_home_url = novel_author_home_url[0].get('href').strip()
# return 'http:' + novel_author_home_url
class ZHNovelsSpider(Spider):
start_urls = ['http://book.zongheng.com/store/c0/c0/b9/u0/p1/v9/s9/t0/ALL.html']
request_config = {
'RETRIES': 8,
'DELAY': 0,
'TIMEOUT': 3
}
concurrency = 60
motor_db = MotorBase(loop=loop).get_db()
async def parse(self, res):
items_data = await ZHNovelsItem.get_items(html=res.html)
tasks = []
for item in items_data:
if item.novel_url:
res_dic = {
'novel_url': item.novel_url,
'novel_name': item.novel_name,
'novel_author': item.novel_author,
'novel_author_home_url': item.novel_author_home_url,
'novel_type': item.novel_type,
'novel_cover': item.novel_cover,
'novel_abstract': item.novel_abstract,
'novel_latest_chapter': item.novel_latest_chapter,
'spider': 'zongheng',
'updated_at': time.strftime("%Y-%m-%d %X", time.localtime()),
}
tasks.append(asyncio.ensure_future(self.save(res_dic)))
# if self.all_novels_col.find_one(
# {"novel_name": item.novel_name, 'novel_author': item.novel_author}) is None:
# self.all_novels_col.insert_one(res_dic)
# # async_callback(self.save, res_dic=res_dic)
# print(item.novel_name + ' - 抓取成功')
good_nums = 0
if tasks:
done_list, pending_list = await asyncio.wait(tasks)
for task in done_list:
if task.result():
good_nums += 1
print(f"{len(tasks)}本小说,抓取成功{good_nums}")
async def save(self, res_dic):
# 存进数据库
res_dic = res_dic
try:
await self.motor_db.all_novels.update_one({
'novel_url': res_dic['novel_url'], 'novel_name': res_dic['novel_name']},
{'$set': res_dic},
upsert=True)
print(res_dic['novel_name'] + ' - 抓取成功')
return True
except Exception as e:
self.logger.exception(e)
return False
if __name__ == '__main__':
# 其他多item示例https://gist.github.com/howie6879/3ef4168159e5047d42d86cb7fb706a2f
# 51793
for page in range(0, 10):
print(f"正在爬取第{page}")
start_page = page * 100
end_page = start_page + 100
if end_page > 999:
end_page = 999
ZHNovelsSpider.start_urls = ['http://book.zongheng.com/store/c0/c0/b9/u0/p{i}/v9/s9/t0/ALL.html'.format(i=i) for
i in
range(start_page, end_page)]
# 其他多item示例https://gist.github.com/howie6879/3ef4168159e5047d42d86cb7fb706a2f
ZHNovelsSpider.start(loop=loop, middleware=[ua_middleware, owl_middleware], close_event_loop=False)

View File

@ -0,0 +1,118 @@
# -*- coding:utf-8 -*-
# !/usr/bin/env python
import asyncio
import time
from pprint import pprint
from ruia import Spider, Item, TextField, AttrField
from ruia_ua import middleware as ua_middleware
from soulbook.database.mongodb import MotorBase
from soulbook.spiders.middlewares import owl_middleware
try:
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
pass
loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
class ZHNovelInfoItem(Item):
"""
定义继承自item的Item类
"""
novel_name = TextField(css_select='div.main div.status h1 a')
author = TextField(css_select='div.main div.status div.booksub a')
# 当提取的值是属性的时候要定义AttrField
cover = AttrField(css_select='div.main div.book_cover img', attr='src')
abstract = TextField(css_select='div.main div.status div.info_con p')
status = AttrField(css_select='div.main div.status h1 em', attr='title')
novels_type = TextField(css_select='div.main div.status div.booksub a')
novel_chapter_url = AttrField(css_select='div.main div.status div.book_btn span.list a', attr='href')
async def clean_author(self, author):
if isinstance(author, list):
return author[0].text
else:
return author
async def clean_status(self, status):
"""
当目标值的对象只有一个默认将值提取出来否则返回list可以在这里定义一个函数进行循环提取
:param ele_tag:
:return:
"""
if isinstance(status, list):
return '#'.join([i.get('title').strip().replace('作品', '') for i in status])
else:
return status
async def clean_novels_type(self, novels_type):
if isinstance(novels_type, list):
try:
return novels_type[1].text
except:
return ''
else:
return ''
class ZHNovelInfoSpider(Spider):
start_urls = []
request_config = {
'RETRIES': 3,
'DELAY': 2,
'TIMEOUT': 10
}
motor_db = MotorBase(loop=loop).get_db()
async def parse(self, res):
item = await ZHNovelInfoItem.get_item(html=res.html)
item_data = {
'novel_name': item.novel_name,
'author': item.author,
'cover': item.cover,
'abstract': item.abstract,
'status': item.status,
'novels_type': item.novels_type,
'novel_chapter_url': item.novel_chapter_url,
'target_url': res.url,
'spider': 'zongheng',
'updated_at': time.strftime("%Y-%m-%d %X", time.localtime()),
}
print('获取 {} 小说信息成功'.format(item_data['novel_name']))
print(item_data)
await self.motor_db.all_novels_info.update_one(
{'novel_name': item_data['novel_name'], 'spider': 'zongheng'},
{'$set': item_data},
upsert=True)
if __name__ == '__main__':
import random
# 其他多item示例https://gist.github.com/howie6879/3ef4168159e5047d42d86cb7fb706a2f
ZHNovelInfoSpider.start_urls = ['http://book.zongheng.com/book/672340.html']
ZHNovelInfoSpider.start(middleware=[ua_middleware, owl_middleware])
# def all_novels_info():
# all_urls = []
#
# for each in ZHNovelInfoSpider.all_novels_col.find({'spider': 'zongheng'}):
# if 'zongheng' in each['novel_url']:
# all_urls.append(each['novel_url'])
# random.shuffle(all_urls)
#
# ZHNovelInfoSpider.start_urls = all_urls
# ZHNovelInfoSpider.start()
#
#
# all_novels_info()

3
soulbook/start.sh Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
ps -ef | grep "gunicorn -c config/gunicorn.py --worker-class sanic.worker.GunicornWorker server:app" | grep -v grep | awk '{print $2}' | xargs kill -9
nohup gunicorn -c config/gunicorn.py --worker-class sanic.worker.GunicornWorker server:app >/dev/null &2>1 &

View File

@ -0,0 +1,41 @@
th, td {
text-align: center !important;
}
table a {
color: #337ab7 !important;
text-decoration: none !important;
}
table a:hover {
color: black !important;
}
.mdui-panel-fluid {
margin-top: 2%;
width: 80%;
margin-left: 10%
}
.email-error, .pass-error {
height: 12px;
margin-top: 8px;
overflow: hidden;
font-size: 12px;
line-height: 12px;
color: #f44336;
text-overflow: ellipsis;
white-space: nowrap;
visibility: hidden;
}
.owl-ranking {
max-width: 300px;
height: 500px;
margin: 5px;
}
.author-name-tag{
margin-left: 10%;
margin-top: 13px;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More