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 实战目标
在 Chrome 浏览器中,输入 Discuz! 论坛的网址 http://172.17.0.2,即可看到论坛的页面。论坛中共有 3 个板块:默认板块、寻找 flag、登陆后寻找 flag。登陆后寻找 flag 仅在用户登录后可见。
寻找 flag 板块中共有 69 个主题,登陆后寻找 flag 板块共有 90 个主题。分别在这两个板块的某一个主题中,隐藏着 flag。
实战目标:编写爬虫,分别遍历两个板块中的所有帖子,从中寻找的到 flag。
flag 的形式为 {flag is XXXXXX}
注:为降低难度,Discuz! 论坛已关闭登录验证码
2. "寻找 flag" 板块分析
2.1 确定板块的 URL
首先在 Chrome 浏览器中,进入 寻找 flag 板块。
观察 Chrome 浏览器中的 URL 地址:
http://172.17.0.2/forum.php?mod=forumdisplay&fid=36
包含了两个请求参数,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 = requests.get('%s/forum.php'
'?mod=forumdisplay'
'&fid=%s' % (config.discuz_url, config.discuz_post_fid))
total_page = int(re.findall(r'title="共 ([\d]+) 页"', resp.content)[0])
2.3 确定板块每页的链接
分别点击页面导航按钮中的第 2 页、第 3 页,观察 Chrome 地址栏中的 URL。
http://172.17.0.2/forum.php?mod=forumdisplay&fid=36&page=2
参数 mod=forumdisplay,fid=36、page=2。
http://172.17.0.2/forum.php?mod=forumdisplay&fid=36&page=3
参数 mod=forumdisplay,fid=36、page=3。
将 URL 中的 page 参数修改为 1,访问 http://172.17.0.2/forum.php?mod=forumdisplay&fid=36&page=1 ,发现可进入第 1 页
因此,板块中的第几页由 URL 的 page 参数控制。
http://172.17.0.2/forum.php?mod=forumdisplay&fid=36&page=%s
Python 中访问第 page 页的代码:
resp = requests.get('%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 = pq(resp.content)('#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 = requests.get('%s/%s' % (config.discuz_url, url))
# 正则表达式寻找 flag
flag = re.findall(r'({flag[^}]*})', resp.content)
3. "登陆后寻找 flag" 板块分析
由于该板块对登陆后用户可见,首先在论坛中注册一个用户。
用户名:test
密码:testtest
邮箱:test@test.com
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 自身的原因,无论登录成功与失败,登录的响应内容均无法正常显示。
可在 Python 代码中,取消以下两行的注释,观察成功、失败的响应内容。
# print resp.content
# exit()
登录失败的响应如下:
if(typeof errorhandle_ls=='function') {errorhandle_ls('登录失败,您还可以尝试 3 次', {'loginperm':'3'});}]]>
登录成功的响应如下:
window.location.href='http://172.17.0.2/./';]]>
因此,可通过判断响应内容是否包含 window.location.href,作为是否成功登录的依据。
Python 判断是否成功登录:
if 'window.location.href' in resp.content:
print '[+] Login success'
else:
print '[-] Login failed'
exit()
3.2 继续分析
接下来的分析过程与 (2. "寻找 flag" 板块分析)[] 中相似。
4. 运行代码
4.1 配置 config.py
discuz_url 为论坛的 URL,注意尾部没有斜杠。
discuz_post_fid 为 寻找 flag 的板块 ID。
discuz_post_login_fid 为 登陆后寻找 flag 的板块 ID。
discuz_username 和 discuz_password 分别为用户名及密码。
discuz_url = 'http://172.17.0.2'
discuz_post_fid = 36
discuz_post_login_fid = 37
discuz_username = 'test'
discuz_password = 'testtest'
4.2 运行
运行 python main_a.py,在 寻找 flag 的板块中寻找 flag:
运行 python main_b.py,在 登陆后寻找 flag 的板块中寻找 flag:
5 实践设计思路
为了避免直接利用 Discuz! 自带的搜索功能搜索到 flag,我将 flag 藏到了图片的 url 链接中。
[img=1,1]https://www.bjcc.gov.cn/resources/pc/img/logo.png?{flag is XXXX}[/img]
在帖子中 flag 出现的代码
python爬取discuz_爬虫技术实践(二)Discuz! 按板块爬取帖子内容实战相关推荐
- python初学者爬虫教程(二)动态网页抓取
python爬虫教程(二)动态网页抓取 解析真实地址抓取 通过selenium 模拟浏览器抓取 selenium 安装与测试 selenium爬取一条评论 selenium获取文章的所有评论 sele ...
- 如何快速掌握 Python 数据采集与网络爬虫技术
摘要: 本文详细讲解了 python 网络爬虫,并介绍抓包分析等技术,实战训练三个网络爬虫案例,并简单补充了常见的反爬策略与反爬攻克手段.通过本文的学习,可以快速掌握网络爬虫基础,结合实战练习,写出一 ...
- 如何快速掌握Python数据采集与网络爬虫技术
云栖君导读:本文详细讲解了python网络爬虫,并介绍抓包分析等技术,实战训练三个网络爬虫案例,并简单补充了常见的反爬策略与反爬攻克手段.通过本文的学习,可以快速掌握网络爬虫基础,结合实战练习,写出一 ...
- python数据采集有哪些技术_如何快速掌握Python数据采集与网络爬虫技术
一.数据采集与网络爬虫技术简介 网络爬虫是用于数据采集的一门技术,可以帮助我们自动地进行信息的获取与筛选.从技术手段来说,网络爬虫有多种实现方案,如PHP.Java.Python ....那么用pyt ...
- Python案例:破译爬虫项目实践活动日期密码
Python案例:破译爬虫项目实践活动日期密码 一.下达编程任务 寒假期间,李铁有幸成为外星人教育Python爬虫项目实践活动的参与者.外星人教育给参加活动的同学都发了一条短信,告知了实践活动日期,但 ...
- python制作电脑软件_利用PYTHON制作桌面版爬虫软件(二)
今天继续新的专题.主要讲解[利用PYTHON制作桌面版爬虫软件]下的如何实现界面功能(一).该讲主要包括以下三个内容:掌握如何编写主函数,运行界面. 了解pywin32模块. 如何用python识别Q ...
- python爬虫之app数据抓取_Python爬虫入门教程 29-100 手机APP数据抓取 pyspider
1. 手机APP数据----写在前面 继续练习pyspider的使用,最近搜索了一些这个框架的一些使用技巧,发现文档竟然挺难理解的,不过使用起来暂时没有障碍,估摸着,要在写个5篇左右关于这个框架的教程 ...
- python 北上资金_python爬虫技术:北向资金数据自动爬取!
好久不见!今天我们继续python的话题啦.python现在势头凶得很,没事刷抖音.刷朋友圈.看公众号,弹出的广告总少不了python."python带你发家致富,财富自由!"广告 ...
- 【Python 爬虫】(二)使用 Requests 爬取豆瓣短评
文章目录 Requests库介绍 Requests库安装 Requests库的简单用法 实战 爬虫协议 Requests库介绍 Requests库官方的介绍有这么一句话:Requests,唯一的一个非 ...
最新文章
- TensorRT Samples: MNIST(Plugin, add a custom layer)
- CSS教你玩转背景background-position(1)
- THUWC 2018(游记)
- comboBox.DataSource绑定
- LAMP 搭建BBS论坛实战
- 【面试必备】java写spark好不好
- php layui 框架,Thinkphp5+Layui高颜值内容管理框架
- php导出csv带图片,PHP导出CSV文件:刚测试过,这个导出CSV可以
- arcmap导出地图快捷键_谷歌点坐标导出为excel表格
- c#点击按钮调出另一个窗体_在类库或winform项目中打开另一个winform项目窗体的方法...
- 1603错误_iPhone恢复iTunes未知错误怎么办【解决方法】
- Dataframe列赋值值后全部为NAN
- Cadence Allegro智能创建PCB封装库
- 深度学习中常用的激励函数
- 视频教程-2020软考网络规划设计师基础知识视频教程-软考
- 操作系统原理:文件系统
- CAP、BASE理论
- 声谱图(spectrogram)、FBank(Mel_spectrogram)和 MFCC(Mel倒谱)到底用哪个作为NN输入?
- Linux 中各个文件夹的作用
- 鹅厂java面试真题汇总