scrapy + gerapy实现百度贴吧每天定时签到
1.Gerapy介绍
scrapy就不用多说了。一个爬虫框架,非常的好用,爬虫效率也高。
gerapy就比较冷门了。简单来说gerapy就是一个分布式爬虫管理框架,我们可以将scrapy项目部署到Scrapyd上,用gerapy进行管理。
gerapy主要功能有:
- 更方便地控制爬虫运行
- 更直观地查看爬虫状态
- 更实时地查看爬取结果
- 更简单地实现项目部署
- 更统一地实现主机管理
- 可以设置定时运行爬虫
这篇文章用百度贴吧签到的例子,来介绍下如何将scrapy项目部署到gerapy上,实现定时运行。
2. 编写scrapy爬虫
2.1 安装scrapy
pip install scrapy
在终端输入scrapy,有以下信息表示安装成功。
2.2 创建一个爬虫项目
在终端输入命令 scrapy startproject Tieba
Tieba是项目名自己随便取。
出现这些信息表示项目创建成功,可以见到当前目录下有个Tieba的目录。
2.3 创建一个爬虫
在终端输入命令cd .\Tieba\
进入项目目录
再输入scrapy genspider main
tieba.baidu.com
命令创建一个爬虫。
其中 genspider是创建爬虫的命令,main为爬虫名,tieba.baidu.com 则是爬虫可以访问的域名。
出现下面这些信息表示爬虫创建成功。
在项目目录spiders目录下有个main.py的文件,就是我们创建的爬虫文件。
2.4 编写配置文件
找到目录下的setting.py文件,其他内容不动,修改下面的内容。
# Obey robots.txt rules
ROBOTSTXT_OBEY = False # 改为False
# 把默认的请求头改为这个。 其中Cookie需要自己先登录贴吧后,刷新页面,查看请求头中的Cookie复制到这里。记得后面还有个.encode('utf-8')。
DEFAULT_REQUEST_HEADERS = {
"USER_AGENT":'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36',
'Cookie':''.encode('utf-8'),
'Referer': 'https://www.baidu.com/',
'Content-Type': 'text/html; charset=UTF-8',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
}
# 取消掉注释
COOKIES_ENABLED = False
# 取消注释,开启管道文件
ITEM_PIPELINES = {
'Tieba.pipelines.TiebaPipeline': 300,
}
2.5 编写main.py爬虫文件
整体的思路是先确定Cookie有效,拿到账号关注的所有贴吧名,在进入到贴吧名主页进行签到。并不是用百度的一键签到功能。
就这样的好处是全部贴吧都可以自动签到,百度的一键签到有些贴吧等级低签到不了。
在parse函数前面添加这些配置
class MainSpider(scrapy.Spider):
name = 'main' # 爬虫名
allowed_domains = ['tieba.baidu.com'] # 爬虫可以访问的域名
start_urls = ['https://tieba.baidu.com/'] # 爬虫开始请求的url
success_count = 0 # 成功签到的吧个数
fail_count = 0 # 签到失败的吧个数
custom_settings = {
'DOWNLOAD_DELAY': 0.3 # 设置爬虫延时,防治请求频繁被封
}
检查一下Cookie是否有效。
def parse(self, response):
user_name = re.findall('"user_id": "\d+", "name": "(.*?)",', response.text)
print(user_name)
终端进入项目目录中的spiders目录下,输入scrapy crawl main --nolog
命令运行爬虫
crawl 是运行命令 main 就是爬虫名 --nolog 取消日志信息。
如果终端输出了我们贴吧的用户名,就表示Cookie就是有效的。
查看贴吧首页的源代码,发现我们关注的贴吧名是这个forum_name。
编写一个正则将关注的贴吧名全部匹配出来
if user_name:
self.logger.info(f'用户: {user_name[0]} 登陆成功!') # 日志提醒登录成功
tieba_name = list(set(re.findall('"forum_name":"(.*?)",',response.body.decode('unicode-escape')))) # 匹配到的数据有重复,需要set去重后在转为list
# response.body.decode('unicode-escape')作用是将响应的数据解码为 Unicode 字符串,默认的数据是“\uXXXX”。
print(tieba_name)
else:
self.logger.info('登陆失败! 请更换Cookie!')
再次运行爬虫,可以看到终端输出了账号关注的贴吧名
有了贴吧名后就可以拼接贴吧名的首页url了。
https://tieba.baidu.com/f?kw=电影交流&fr=index,可以发现kw=后面就是跟着贴吧名。
直接一个循环就ok了
if user_name:
self.logger.info(f'用户: {user_name[0]} 登陆成功!')
tieba_name = list(set(re.findall('"forum_name":"(.*?)",',response.body.decode('unicode-escape'))))
for name in tieba_name:
tieba_url = f'https://tieba.baidu.com/f?kw={name}&fr=index&fp=0&ie=utf-8'
else:
self.logger.info('登陆失败! 请更换Cookie!')
else:
self.logger.info('登陆失败! 请更换Cookie!')
这样就拼接好了贴吧主页的url了。在贴吧主页点击签到,查看对应的网络请求。
请求方式和url
携带的参数
返回值
我们只要带好请求参数,发送post请求就好了,问题是这个tbs是什么参数,哪里来的。
查看贴吧名主页的源代码,发现tbs就在源代码里面。
所以我们还得先对贴吧名主页请求一次,拿到签到要的参数,再进行post请求。
def parse(self, response):
user_name = re.findall('"user_id": "\d+", "name": "(.*?)",', response.text)
if user_name:
self.logger.info(f'用户: {user_name[0]} 登陆成功!')
tieba_name = list(set(re.findall('"forum_name":"(.*?)",',response.body.decode('unicode-escape'))))
for name in tieba_name:
tieba_url = f'https://tieba.baidu.com/f?kw={name}&fr=index&fp=0&ie=utf-8'
yield scrapy.Request(tieba_url,callback=self.get_tbs,meta={'name':name}) # 调用get_tbs函数,meta={'name':name} 将name作为参数带过去
else:
self.logger.info('登陆失败! 请更换Cookie!')
def get_tbs(self,response):
name = response.meta['name'] 获取带过来的参数
print(response.url)
tbs = re.findall('\'tbs\': "(.*?)" };',response.text)
print(tbs)
构造post参数,进行签到
def get_tbs(self,response):
name = response.meta['name']
tbs = re.findall('\'tbs\': "(.*?)" };',response.text)
if tbs:
post_data = {
'ie': 'utf-8',
'kw': name,
'tbs': tbs[0]
post_url = 'https://tieba.baidu.com/sign/add'
yield scrapy.FormRequest(post_url,formdata=post_data,callback=self.QiaoDao,meta={'name':name})
def QiaoDao(self,response):
name = response.meta['name']
data = json.loads(response.text)
if data['no'] == 0:
self.logger.info(f'{name}吧 签到成功!经验+{data["data"]["sign_version"]}')
self.success_count += 1
else:
self.logger.info(f'{name}吧 签到失败!原因:{data["error"]}')
self.fail_count += 1
main.py 全部代码
import scrapy
import re,json
class MainSpider(scrapy.Spider):
name = 'main'
allowed_domains = ['tieba.baidu.com']
start_urls = ['https://tieba.baidu.com/']
success_count = 0
fail_count = 0
custom_settings = {
'DOWNLOAD_DELAY': 0.3
}
def parse(self, response):
user_name = re.findall('"user_id": "\d+", "name": "(.*?)",', response.text)
print(user_name)
if user_name:
self.logger.info(f'用户: {user_name[0]} 登陆成功!')
tieba_name = list(set(re.findall('"forum_name":"(.*?)",',response.body.decode('unicode-escape'))))
for name in tieba_name:
tieba_url = f'https://tieba.baidu.com/f?kw={name}&fr=index&fp=0&ie=utf-8'
yield scrapy.Request(tieba_url,callback=self.get_tbs,meta={'name':name})
else:
self.logger.info('登陆失败! 请检查更换Cookie!')
def get_tbs(self,response):
name = response.meta['name']
tbs = re.findall('\'tbs\': "(.*?)" };',response.text)
if tbs:
post_data = {
'ie': 'utf-8',
'kw': name,
'tbs': tbs[0]
}
post_url = 'https://tieba.baidu.com/sign/add'
yield scrapy.FormRequest(post_url,formdata=post_data,callback=self.QiaoDao,meta={'name':name})
def QiaoDao(self,response):
name = response.meta['name']
data = json.loads(response.text)
if data['no'] == 0:
self.logger.info(f'{name}吧 签到成功!经验+{data["data"]["sign_version"]}')
self.success_count += 1
else:
self.logger.info(f'{name}吧 签到失败!原因:{data["error"]}')
self.fail_count += 1
pipelines.py
from itemadapter import ItemAdapter
class TiebaqiandaoPipeline:
def process_item(self, item, spider):
return item
def close_spider(self,spider):
spider.logger.info(f'签到结束!\n成功签到{spider.success_count}个吧!\n签到失败{spider.fail_count}个吧!')
这样签到脚本就算是全部写完了。
scrapy crawl main
运行爬虫
签到脚本写完后,接下来就是将scrapy项目部署道gerapy上。
3.gerapy 使用
3.1 gerapy安装
pip install gerapy
pip install Scrapyd
两个都要装
3.2 gerapy初始化
在终端输入命令 gerapy init
自己会生成一个gerapy的目录
3.3 gerapy数据库初始化
进入gerapy目录在终端输入命令 gerapy migrate
3.4 建立超级用户
终端输入命令 gerapy createsuperuser
3.5 启动 gerapy服务
终端输入命令 gerapy runserver
3.6 访问 gerapy
浏览器输入 http://127.0.0.1:8000/
输入刚刚创建的账户和密码
3.7 添加主机
在gerapy相同的目录下创建一个scrapyd的文件夹,新开一个终端进入到这个文件夹的目录下
输入命令 Scrapyd
启动Scrapyd服务
在网页上添加一台主机
3.8 上传项目
直接把整个Tieba目录 复制到gerapy目录下的project目录
在网页上点开项目管理,可以发现项目已经上传了
![](/media/upload/2730ecfc4d2b44689d1bf755e4442bf5.png)
3.9 项目部署打包
点击操作中的部署
![](/media/upload/1ae49e338f0a48b5a51a69d6c519af28.png)
先点击打包,提示打包成功后在点击部署。
部署成功后在主机调度中可以看到爬虫了
![](/media/upload/ce3ad21720cd42c5970d9b8b7ab5b8ff.png)
点击运行,可以去scrapyd目录下查看对应的运行日志
运行日志没报错,说明我们的爬虫没有问题,接下来就是设置定时任务了。
3.10 设置定时任务
在网页上点击任务管理,点击创建任务。这里我设置一分钟后执行,看他会不会运行。
查看运行日志发现正常运行了
间隔一天运行按下图配置就行。
- 名称:可以随便写
- 项目:要与scrapy的项目名一致
- 爬虫:要与scrapy的项目里的爬虫名一致
- 主机:自己选
- 调度方式:interval按间隔运行,隔天的话就选它,自己可以设置个开始时间,还有其他选择,可以按自己需求来
- 时区:选上海
- 开始时间:看自己
在任务状态中还可以看下次运行时间以及运行的成功率
![](/media/upload/cdd6f032079c4da9a8be6f39593ddcd0.png)
这样全部流程都弄完了,可以把项目放到服务器上在后台运行,就可以实现每天自动签到百度贴吧啦。
自己第二天可以检查爬虫是否正常运行,没有运行日志一般就是没有运行。
贴吧的Cookie好像持续时间还挺久的,不过用脚本频繁请求可能也会被验证,也需要更换Cookie。
手动更换还是比较麻烦的,主要是博主不知道怎么实现自动登录获取Cookie。
1 #