python爬取discuz_爬⾍技术实践(⼆)Discuz!按板块爬取帖
⼦内容实战
Discuz! 是⼀套由康盛创想开发的通⽤社区论坛软件系统,成熟度⾼、覆盖率⼤。⽤户可以在不需要任何编程的基础上,通过简单的设置和安装,在互联⽹上搭建起具备完善功能、很强负载能⼒和可⾼度定制的论坛服务。Discuz! 的基础架构采⽤ PHP + MySQL 实现。
1. 实战环境
由 Ubuntu、Nginx、PHP、MySQL 配置的 Discuz! Docker 环境可从以下链接中下载:
Docker 镜像下载地址
提取码:esdm
1.1 环境配置
1.1.1 配置 Python 环境
Python、requests、pyquery
Python 依赖安装:
pip install requests pyquery
1.1.2 导⼊ Docker 镜像
$ sudo docker load ubuntu-nginx-php-mysql-discuz-exp-2.tar
1.1.3 启动环境
查看 ubuntu-nginx-php-mysql-discuz:exp-2 的 IMAGE ID
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu-nginx-php-mysql-discuz exp-2 368753f87d4f 22 hours ago 1.02GB
镜像的 IMAGE ID 为 368753f87d4f
启动 ubuntu-nginx-php-mysql-discuz:exp-2
$ sudo docker run -itd {IMAGE ID}
1.1.4 进⼊ Docker 容器
查看已运⾏的 Docker 容器
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a37b8fa69b5d 368753f87d4f "/bin/bash" 40 seconds ago Up 38 seconds optimistic_hypatia
容器的 CONTAINER ID 为 a37b8fa69b5d
进⼊容器
$ sudo docker attach {CONTAINER ID}
1.1.5 在容器中启动服务
启动 Nginx PHP Mysql 服务,进⼊ /root ⽂件夹,运⾏ start.sh
# cd /root
# bash start.sh
1.1.6 获取容器的 IP 地址
# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:32 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3721 (3.7 KB) TX bytes:0 (0.0 B)
容器的 IP 地址为 172.17.0.2
在键盘上依次按下 Ctrl + P + Q 退出容器并后台继续运⾏
1.2 实战⽬标
寻 flag 板块中共有 69 个主题,登陆后寻 flag 板块共有 90 个主题。分别在这两个板块的某⼀个主题中,隐藏着 flag。实战⽬标:编写爬⾍,分别遍历两个板块中的所有帖⼦,从中寻的到 flag。
flag 的形式为 {flag is XXXXXX}
注:为降低难度,Discuz! 论坛已关闭登录验证码
2. "寻 flag" 板块分析
2.1 确定板块的 URL
⾸先在 Chrome 浏览器中,进⼊ 寻 flag 板块。
观察 Chrome 浏览器中的 URL 地址:
包含了两个请求参数,mod=forumdisplay,fid=36。
Discuz! 字段说明
字段
含义
说明
fid
板块 ID
论坛上每个版块的编号
tid
主题 ID
每个主题帖的唯⼀编号
pid
帖⼦ ID
每个帖⼦的唯⼀编号
uid
⽤户 ID
每个注册⽤户的编号
因此可知,寻 flag 板块 ID 为 36。
2.2 确定板块的总页数
观察板块页⾯的最下⽅,可看到页⾯的导航按钮。
进⼊ Chrome 调试模式(Ctrl + Shift + I),检查上图中的元素,可看到⽹页的源代码
可看到总页数出现在 title="共 4 页" 中,因此可⽤ 正则表达式 获取到板块的总页数。正则表达式为 title="共 ([\d]+) 页"。获取板块总页数的 Python 代码:
resp = ('%s/forum.php'
'?mod=forumdisplay'
'&fid=%s' % (config.discuz_url, config.discuz_post_fid))
total_page = int(re.findall(r'title="共 ([\d]+) 页"', t)[0])
2.3 确定板块每页的链接discuz系统
分别点击页⾯导航按钮中的第 2 页、第 3 页,观察 Chrome 地址栏中的 URL。
参数 mod=forumdisplay,fid=36、page=2。
参数 mod=forumdisplay,fid=36、page=3。
因此,板块中的第⼏页由 URL 的 page 参数控制。
Python 中访问第 page 页的代码:
resp = ('%s/forum.php'
'?mod=forumdisplay'
'&fid=%s'
'&page=%s' % (config.discuz_url, config.discuz_post_fid, page))
2.4 确定每个主题的链接
在 Chrome 调试页⾯中,检查主题列表
主题列表均在 id 为 threadlisttableid 的 table 标签中。每个主题以 tbody 标签的形式出现。
注意:id="separatorline" 的 tbody 不是主题。
Python 使⽤ pyquery 获取到主题列表:
articles = t)('#threadlisttableid tbody')
在 tbody 标签中,可以看到,主题的 URL 出现在 class 为 xst 的 a 标签中,URL 为该标签的 href 属性。
Python 获取主题的 title 及 URL
# 确定 title 和 url
title = tbody_pq.find('th a.xst').text()
url = tbody_pq.find('th a.xst').attr('href')
2.5 遍历所有主题获取 flag
由于已知 flag 的形式为 {flag is XXXXXX},因此可使⽤正则表达式直接在主题请求的响应内容中寻 flag。正则表达式为 ({flag[^}]*})。# 请求帖⼦的 url
resp = ('%s/%s' % (config.discuz_url, url))
# 正则表达式寻 flag
flag = re.findall(r'({flag[^}]*})', t)
3. "登陆后寻 flag" 板块分析
由于该板块对登陆后⽤户可见,⾸先在论坛中注册⼀个⽤户。
⽤户名:test
密码:testtest
邮箱:test@test
3.1 登录分析
注册成功后会直接进⼊登录后的页⾯,由于爬⾍需要模拟登录的过程,⾸先退出登录。
在登录框内输好⽤户名、密码后,打开 Chrome 调试页⾯,进⼊ Network 中,勾选 Preserve log。
点击 登录 按钮,Chrome 会截取到登录的请求。
在 POST 的请求中,URL包含了 5 个参数
Key
Value
mod
logging
action
login
loginsubmit
yes
infloat
yes
lssubmmit
yes
inajax
1
Form Data 中包含了 5 个参数
Key
Value
fastloginfield
username
username
test
password
testtest
quickforward
yes
handlekey
ls
可见,⽤户名、密码在 From Data 中的 username、password。
Python 构造 请求 url 及 Form Data:
url = '%s/member.php' \
'?mod=logging' \
'&action=login' \
'&loginsubmit=yes' \
'&infloat=yes' \
'&lssubmit=yes' \
'&inajax=1' % config.discuz_url
data = {
'fastloginfield': 'username',
'username': config.discuz_username,
'password': config.discuz_password,
'quickforward': 'yes',
'handlekey': 'ls'
}
在登录成功的响应头中,包含了 set-cookie。
为了使请求能够⾃动处理好 Cookie 的问题,使⽤:
req = requests.session()
由于 Chrome ⾃⾝的原因,⽆论登录成功与失败,登录的响应内容均⽆法正常显⽰。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论