-
为避免
python
版本不一致导致的不兼容问题,建议在python3.10
环境运行。 -
需要安装
twscrape
库:pip3 install twscrape
本仓库有两个模块的源代码,一个是src
,另一个是twsrc
。其中,src
是基于snscrape
写的爬取代码,由于2023年7月份推特政策的更新,无法以游客身份继续爬取数据,因此已不可用。twsrc
是基于twscrape
写的爬取代码,需要购买账号登录,以完成爬取。
运行脚本是run-pooled.sh
,运行前需要设置相应的变量:
-
DIVIDE_DIR
应该是一个包含有若干txt
文件的文件夹,其中每个txt
文件的每一行是一个需要爬取的关键词。 -
DOWNLOAD_DIR
是下载到的数据与log
文件存放的文件夹。
此外,需要在代码中修改爬取的时间段。具体来说如果爬取模式为多进程或者多线程下载,应该要修改code/pooled_download.py
中的:
def pooled_download(args: Namespace):
...
def _get_configs(counter_callback = lambda: None):
temp_count: int = 0
used_keys = get_used_keys(args)
download_configs: List[Tuple[tuple, int]] = []
for key in keys:
for month in range(12 * 12):
if (key, month) not in used_keys:
until = datetime.datetime(*date_minus((2022, 12), month), day = 1)
since = datetime.datetime(*date_minus((2022, 12), month + 1), day = 1)
temp_file_path = os.path.join(temp_dir, f'{temp_count :06d}.jsonl')
download_configs.append(((key, temp_file_path, until, since), month))
temp_count += 1
counter_callback()
return download_configs
...
设置好后使用命令bash run-pooled.sh
即可开始运行。
该模块基于twscrape
库。该库是基于用户账号的推特爬取库,使用该库时,账号的登录信息会存储在当前目录的accounts.db
(以sqlite3
数据库格式)。安装twscrape
后可以直接在终端调用twscrape
,可以测试是否在正常工作,例:
twscrape search china --limit 5
注:以上命令需要在当前目录的accounts.db
已经注册过账号后使用。
可以用模块调用的形式调用twsrc
模块:
python3 -m twsrc --help
该命令会输出使用该模块的基本方式。在进一步运行代码之前,建议先完成后文一些注意事项中的步骤。
在本仓库中,已经包含了几个默认的配置文件,分别是twsrc/accounts.txt
,存储了测试用的账号信息;以及twsrc/keywords-demo.txt
,存储了测试用的需要爬取的关键词。运行以下代码可以对该关键词进行爬取:
python3 -m twsrc --keywords twsrc/keywords-demo.txt
在登录账号后,程序应该会输出以下信息:
totally 1 keywords
starting download for keyword "deepin since:2017-08-09 until:2017-08-10"
scraping end, keyword = "deepin since:2017-08-09 until:2017-08-10", count = 71 (1 / 1 = 100.00%), time = 5.18s, total time = 0:00:05, average time = 5.18s, average data = 71.00
随后检查当前目录下的downloads
文件夹,应该可以看到以jsonl
格式存储的爬取数据。
-
修改
twscrape
源码,使其支持推特的新域名(x.com
)。详见github issue,在推特更改版本后修改了验证邮件信息的中的域名信息,会导致其邮件验证模块失效。当前
pip
源似乎没有同步最新版本的twscrape
,可以手动在本地的pip
文件夹处修改其源码,具体在twscrape.imap._wait_email_code
函数,有以下内容:... if min_t is not None and msg_time < min_t: return None if "[email protected]" in msg_from and "confirmation code is" in msg_subj: # eg. Your Twitter confirmation code is XXX return msg_subj.split(" ")[-1].strip() ...
修改为:
... # if min_t is not None and msg_time < min_t: # return None if "[email protected]" in msg_from and "confirmation code is" in msg_subj: # eg. Your Twitter confirmation code is XXX return msg_subj.split(" ")[-1].strip() ...
-
[可选] 修改
twscrape
源码,减少其超速等待时间。由于推特政策的更改,每个账号的爬取速率存在一个限制。具体而言,发送的请求会返回一个
(88) Rate limit exceeded
错误信息。此时可以选择暂停该账号的使用,一段时间后再继续使用该账号爬取。在twscrape
中该等待时间的默认值为4小时,实际上有点过于保守了,经实测可能设置为15分钟就足够。具体在twscrape.queue_client.QueueClient._check_rep
函数,有以下内容:... # possible new limits for tweets view per account if msg.startswith("(88) Rate limit exceeded") or rep.status_code == 429: await self._close_ctx(utc_ts() + 60 * 60 * 4) # lock for 4 hours raise RateLimitError(msg) ...
修改为:
... # possible new limits for tweets view per account if msg.startswith("(88) Rate limit exceeded") or rep.status_code == 429: await self._close_ctx(utc_ts() + 60 * 15) # lock for 15 minutes raise RateLimitError(msg) ...
由于twscrape
是基于异步协程写的,直接在python
脚本用multiprocessing
等库开启多进程支持容易导致程序崩溃,因此建议使用bash
脚本同时开启多个爬虫程序,以实现多进程爬取。
相关参考代码可见tw-multi/twsrc-multi.sh
,大体思路是先确定多进程的并发数,然后用split.py
脚本将原账号、代理和关键词文件均分到若干个子文件夹,然后在各个子文件中调用twsrc
模块。
需要注意该脚本是爬取中国科技实体数据时编写,不一定适用于其它使用情况。
此外也可以基于上述思路用一个python
主进程管理爬虫子进程,以实现动态分配给每个子进程需要爬取的内容,避免关键词划分不均衡。(没写相关脚本)