├── .gitignore ├── README.md ├── README_en.md ├── config.json ├── config.py ├── emotion.json ├── filter.py ├── scrapy.cfg └── tieba ├── __init__.py ├── commands ├── __init__.py └── run.py ├── items.py ├── middlewares.py ├── pipelines.py ├── settings.py └── spiders ├── __init__.py ├── emotion.py ├── helper.py └── tieba_spider.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.py[cod] 3 | *$py.class 4 | *.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tieba_Spider 2 | [Readme(EN)](README_en.md) 3 | 4 | 贴吧爬虫。 5 | 6 | 7 | ## 依赖参考 8 | Python >= 3.6 9 | 10 | mysql >= 5.5 11 | 12 | beautifulsoup4 >= 4.6.0 13 | 14 | **scrapy == 2.4.1** 15 | 16 | mysqlclient >= 1.3.10 17 | 18 | ## 使用方法 19 | 先打开config.json文件,在其中配置好数据库的域名、用户名和密码。接着直接运行命令即可: 20 | ``` 21 | scrapy run <贴吧名> <数据库名> <选项> 22 | ``` 23 | 其中贴吧名不含末尾的“吧”字,而数据库名则是要存入的数据库名字,数据库在爬取前会被创建。例如 24 | ``` 25 | scrapy run 仙五前修改 Pal5Q_Diy 26 | ``` 27 | 但若要在控制台输入中文(非ASCII字符),请确保控制台编码为UTF8。 28 | 29 | 若在config.json里面已经配置好贴吧名和对应数据库名,则可以忽略数据库名。若忽略贴吧名,则爬取config.json里面DEFAULT的数据库。 30 | 31 | **特别提醒** 任务一旦断开,不可继续进行。因此SSH打开任务时,请保证不要断开连接,或者考虑使用后台任务或者screen命令等。 32 | 33 | ## 选项说明 34 | 35 | |短形式|长形式 |参数个数|作用 |举例 | 36 | |------|-----------|--------|----------------------------------|-------------------------------| 37 | |-p |--pages |2 |设定爬取帖子的开始页和结束页 |scrapy run ... -p 2 5 | 38 | |-g |--good_only|0 |只爬精品帖 |scrapy run ... -g | 39 | |-s |--see_lz |0 |只看楼主,即不爬非楼主的楼层 |scrapy run ... -s | 40 | |-f |--filter |1 |设定帖子过滤函数名(见`filter.py`) |scrapy run ... -f thread_filter| 41 | 42 | 举例: 43 | ``` 44 | scrapy run 仙剑五外传 -gs -p 5 12 -f thread_filter 45 | ``` 46 | 使用只看楼主模式爬仙剑五外传吧精品帖中第5页到第12页的帖子,其中能通过过滤器`filter.py`中的`thread_filter`函数的帖子及其内容会被存入数据库。 47 | 48 | ## 数据处理 49 | 对爬取的数据并非原样入库,会进行一些处理。 50 | 51 | 1. 广告楼层会被去掉(右下角有“广告”两字的楼层)。 52 | 2. 加粗和红字效果丢失为纯文本(beautifulsoup的get_text功能)。 53 | 3. 常用表情会转换为文字表达(emotion.json,欢迎补充)。 54 | 4. 图片和视频会变成对应链接(要获取视频链接需要拿到一个302响应)。 55 | 56 | ## 数据保存结构 57 | - thread 58 | 59 | 为各帖子的一些基本信息。 60 | 61 | |属性 |类型 |备注 | 62 | |---------|------------|--------------------------------------------------------| 63 | |id |BIGINT(12) |"http://tieba.baidu.com/p/4778655068" 的ID就是4778655068| 64 | |title |VARCHAR(100)| | 65 | |author |VARCHAR(30) | | 66 | |reply_num|INT(4) |回复数量(含楼中楼, 不含1楼) | 67 | |good |BOOL |是否为精品帖 | 68 | 69 | 70 | - post 71 | 72 | 为各楼层的一些基本信息,包括1楼。 73 | 74 | |属性 |类型 |备注 | 75 | |-----------|-----------|----------------------| 76 | |id |BIGINT(12) |楼层也有对应ID | 77 | |floor |INT(4) |楼层编号 | 78 | |author |VARCHAR(30)| | 79 | |content |TEXT |楼层内容 | 80 | |time |DATETIME |发布时间 | 81 | |comment_num|INT(4) |楼中楼回复数量 | 82 | |thread_id |BIGINT(12) |楼层的主体帖子ID,外键| 83 | 84 | 85 | - comment 86 | 87 | 楼中楼的一些信息。 88 | 89 | |属性 |类型 |备注 | 90 | |-------|-----------|--------------------------| 91 | |id |BIGINT(12) |楼中楼也有ID,且和楼层共用| 92 | |author |VARCHAR(30)| | 93 | |content|TEXT |楼中楼内容 | 94 | |time |DATETIME |发布时间 | 95 | |post_id|BIGINT(12) |楼中楼的主体楼层ID,外键 | 96 | 97 | 爬取方式决定了comment有可能先于对应的post被爬取,从而外键错误。因此任务开始阶段数据库的外键检测会被关闭。 98 | 99 | ## 耗时参考 100 | 耗时和服务器带宽以及爬取时段有关,下面是我的阿里云服务器对几个贴吧的爬取用时,仅供参考。 101 | 102 | |贴吧名 |帖子数|回复数 |楼中楼数|用时(秒)| 103 | |----------|------|-------|--------|--------| 104 | |pandakill |3638 |41221 |50206 |222.2 | 105 | |lyingman |11290 |122662 |126670 |718.9 | 106 | |仙剑五外传|67356 |1262705|807435 |7188 | 107 | 108 | 下面几个吧是同一时刻爬取的: 109 | 110 | |贴吧名 |帖子数|回复数|楼中楼数|用时(秒)| 111 | |-----------|------|------|--------|--------| 112 | |仙五前修改 |530 |3518 |7045 |79.02 | 113 | |仙剑3高难度|2080 |21293 |16185 |274.6 | 114 | |古剑高难度 |1703 |26086 |32941 |254.0 | 115 | 116 | **特别提醒** 请注意下爬取数据的占用空间,别把磁盘占满了。 117 | 118 | ## 更新日志 119 | 更新后请先删除原有的日志`spider.log`。 120 | 121 | 2020-08-09更新:解决了只爬楼中楼前10层的问题。注:由于python官方已放弃对python 2的支持,此后版本将不再保证python 2能正常运行。 122 | 123 | 2020-02-23更新:解决了被百度识别为爬虫返回403的问题。 124 | 125 | 2018-06-13更新:新增支持python 3。请卸载原来的python库`mysql-python`,改为使用`mysqlclient`。 126 | 127 | 2017-03-23更新:修改了页选项参数形式,增加了只看楼主、只爬精品和自定义过滤帖子功能。 128 | 129 | ## 参考文献 130 | [Scrapy 1.0 文档][1] 131 | 132 | [Scrapy 源代码][2] 133 | 134 | [Beautiful Soup的用法][3] 135 | 136 | [Ubuntu/Debian 安装lxml的正确方式][4] 137 | 138 | [Twisted adbapi 源代码][5] 139 | 140 | [mysql升级8.0后遇到的坑][6] 141 | 142 | 有什么问题或建议欢迎到[我的主页][7]留言~ 143 | 144 | [1]: http://scrapy-chs.readthedocs.io/zh_CN/1.0/ 145 | [2]: https://coding.net/u/fmyl/p/scrapy 146 | [3]: https://cuiqingcai.com/1319.html 147 | [4]: http://www.cnblogs.com/numbbbbb/p/3434519.html 148 | [5]: https://github.com/twisted/twisted/blob/twisted-16.5.0/src/twisted/enterprise/adbapi.py 149 | [6]: https://www.shiqidu.com/d/358 150 | [7]: https://aqua.hk.cn/Programming/oew0fr/ 151 | -------------------------------------------------------------------------------- /README_en.md: -------------------------------------------------------------------------------- 1 | # Tieba_Spider 2 | [Readme(CN)](README.md) 3 | 4 | Spider for [Baidu Tieba](https://tieba.baidu.com). Crawl threads, posts and comments, and store them into MySQL database. 5 | 6 | ## Dependency 7 | Python >= 3.6 8 | 9 | mysql >= 5.5 10 | 11 | beautifulsoup4 >= 4.6.0 12 | 13 | scrapy >= 2.4 14 | 15 | mysqlclient >= 1.3.10 16 | 17 | ## Usage 18 | First time: Edit `config.json`. Fill in database host, username as well as password. 19 | 20 | Command: 21 | ``` 22 | scrapy run