Linux shell爬虫实现树洞网自动回复Robot

奇怪的赞数

人生在世,不如意事十之八九,可与言者无二三人。幸好我们生在互联网时代,现实中找不到可以倾诉的人还可以在网络上寻找发情绪宣泄口,树洞这类产品就是提供一个让人在网络上匿名倾诉的平台。

我是偶然间发现了这个平台:http://www.6our.com/,感觉自己比较惨的时候去看看别人的不如意,发现上帝还是蛮眷顾自己的(也不知道中国在不在他老人家的管辖范围内)。不过我发现了一个奇怪的现象:秘密有一个赞和踩的功能,但是我看到的秘密的赞都没有发现有低于2的,然后尝试着发了一条,发现刚发出来就有两个赞,所以我猜测网站的开发者设定了秘密发出来时候赞的数量就是2,但是作为一个死心眼的程序员,认为只有亲手证过的才是可信的,所以我要验证一下我的想法,于是用shell写了个爬虫,爬取所有秘密的赞的数量,爬虫代码如下:

#! /bin/bash

######################################################
#
#
#
#  树洞网赞数抓取
#
#
######################################################

# env
cd `dirname $0`
source utils.sh

# 初始化线程数控制,使用10个线程并发抓取以免把树洞网站打死
init_thread 250 10

# 初始化业务相关变量
url="http://www.6our.com/qiushi?&p="
total_page_num=`curl_ "${url}1" | grep -oE "<a href=‘/qiushi\?\&p=2480‘ >最后一页</a>" | grep -oE "[0-9]+"`
log "total_page_num $total_page_num"

# 开始抓取列表
for page_num in `seq 1 $total_page_num`;
do
	read -u250
	{
		cur_page_url="${url}${page_num}"
		log "url ${cur_page_url} begin"
		curl_ $cur_page_url | grep -oE "id=\"yes-[0-9]+\">[0-9]+" | sed -n ‘s/id="yes-//; s/">/ /p‘ >> shudong-id-yes.data
		log "url ${cur_page_url} end"
		echo ‘‘ >&250
	}&
done

wait
log "all done"

需要引入的公共库:

################################
#
#  工具库,用来存放一些通用的方法
#
################################

# ha! 简易的log4shell
log(){
	echo "[`date +‘%F %T‘`] $1"
}

# 封装的线程控制器
# $1 要使用的管道
# $2 要使用的线程数
init_thread(){
	pipe_num=$1
	thread_num=$2

	fifo_path="/tmp/fifo_path_`date +%s`_${1}_${2}"
	mkfifo $fifo_path
	eval "exec ${pipe_num}<>${fifo_path}"
	rm $fifo_path

	for i in `seq 1 $thread_num`;
	do
		echo ‘‘ >&${pipe_num}
	done
	return $pipe_num
}

# 对curl的一层封装
# 1. 伪装下U-A
# 2. 模拟浏览器持久cookie的行为
# 3. 安静模式,不显示统计信息
# [email protected] 会被放在最后
curl_(){
	curl -s --user-agent "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36"  -b cookie -c cookie [email protected]
}

# 类似于Stream.map()的封装,使得自定义函数支持管道调用
# $1 函数名
map(){
	function_name=$1
	while read line
	do
		$function_name "$line"
	done
}

看下爬下来多少条评论数据:

不到五万条,如果这五万条中没有一个点赞数小于2的,那么就说明我的猜想是正确的,好,先看下数据格式:

第一列为秘密id,第二列为此秘密的赞数,筛选出第二列为1的共有多少条:

这…这…这就尴尬了,选一些出来看看页面是不是这样显示的:

这个是详情页的url模式:http://www.6our.com/article/{article_id},选一个id拼接处url http://www.6our.com/article/55840 进去看一下:

果然只有一个赞,又选了几个其它的进去看了一下发现都是一个赞。还好证了一下,不然就给出错误的结论了。

我能做点什么

我原来以为开发网站的程序员是送关怀来着,结果不是。于是我就在想,我能不能为他们做点什么呢?于是我去注册了一个账号:

然后写了个脚本,去检测页面内容,根据秘密内容进行回复,对他们送上一些鼓励的话,脚本内容:

#! /bin/bash
##############################################################
#
#
#
#       树洞鼓励师
#
#
#
##############################################################

# env
cd `dirname $0`
source utils.sh

# 模拟登陆,保存cookie
login(){
	username="foo"
	passwd="bar"

	# 虽然不确定__hash__是做什么用的,但还是带上一下
	hash_param=`curl_ "http://www.6our.com/index.php/User/Index/login" | grep -oE "[0-9a-z]+\_[0-9a-z]+" | tail -n 1`
	curl_  -d "account=${username}&password=${passwd}&remember_me=1&submit=&__hash__=$hash_param" "http://www.6our.com/index.php/User/Index/checkLogin"  		| grep "登录成功" >> /dev/null

	if [ $? -ne 0 ];
	then
		log "login failed."
		exit -1
	else
		log "login success"
	fi
}

# 回复秘密
# $1 秘密id
# $2 回复内容
replay(){
	id=$1
	content=$2

	# 检测已有评论避免重复回复,此处的重复是指对每条秘密回复一次,而不是对每个pattern回复一次
	my_name="树洞鼓励师"
	curl_ -d "id=$id" "http://www.6our.com/index.php/Reply/showReply" | grep $my_name >> /dev/null
	if [ $? -eq 0 ];
	then
		return
	fi

	result=`curl_ -d "pid=${id}&anonymous=0&arcontent=${content}" "http://www.6our.com/index.php/Reply/checkReply2"`
	if [ $result -eq 1 ];
	then
	       log "replay $id $content success"
	else
		log "replay $id $content failed"
	fi
	# 防止回复过快
	sleep 3
}

# 检查符合特定的条件则恢复特定内容
# $1 秘密内容
# $2 perl正则模式
# $3 回复内容
check_pattern_and_replay(){
	content=$1
	id=`echo $content | grep -oP ‘id="content-\d+"‘ | grep -oP ‘\d+‘`
	pattern=$2
	replay_content=$3

	echo $content | grep -P $pattern >> /dev/null
	[[ $? -eq 0 ]] &&  replay $id $replay_content
}

# 对单个的秘密检测处理
# $1 秘密元素,包含id和内容
process_single(){
	content=$1

	# 热血青年
	check_pattern_and_replay $content "需要帮助|阻碍|困难|梦想|努力" "加油,明天会更好!"

	# 孤独,纵有千种风情,更与何人说
	check_pattern_and_replay $content "(烦|讨厌|不喜欢).*社交" "跟人打交道是很难的事"

	# 自杀倾向
	check_pattern_and_replay $content "离开人世|自杀|我死了" "活着才有希望"

	# 拯救颜值
	check_pattern_and_replay $content "长的丑" "长的丑的来看下我长得有多挫,助你找回信心 :)"

}

# 监控第一页
monitor(){
	while true;
	do
	 	curl_ "http://www.6our.com/qiushi" | tr -d "\r\n" | grep -oP ‘id="content-\d+".+?</div>‘ | map "process_single"
		log "look first page over"
		sleep 10
	done
}

login
monitor

效果:

所有脚本代码已经放到github: https://github.com/CC11001100/6our-robot

备注:

在调试正则的时候写了一个“foo|”类型的正则,导致有一部分在测试时进行了错误的评论,看到之后赶紧ctrl+c了,但是还是有几个评论删不掉了,吸取教训,以后细心一点。

.

原文地址:https://www.cnblogs.com/cc11001100/p/8973955.html

时间: 2024-11-03 09:27:00

Linux shell爬虫实现树洞网自动回复Robot的相关文章

LINUX SHELL脚本攻略笔记[速查]

Linux Shell脚本攻略笔记[速查] 资源 shell script run shell script echo printf 环境变量和变量 pgrep shell数学运算 命令状态 文件描述符和重定向 cat 数组和关联数组 alias date 调试脚本 函数和参数 管道 读取命令输出 read 字段分隔符和迭代器 循环 比较和测试 find xargs tr md5sum sha1sum 对目录进行校验 sort uniq tempfile split bash变量匹配切分 exp

Linux Shell脚本教程

v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} Normal 0 false 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {

《Linux Shell 脚本攻略》读书笔记

本书主要讲解一些linux shell命令的用法,讲解一些shell的奇技淫巧. 第一章 小试牛刀 主要介绍一些基本shell指令 终端打印:echo.printf 别名:alias 终端处理工具:tput,stty 日期:date 第二章 命令之乐 介绍一些基本命令 读取.显示.拼接文件:cat 录制回放会话:script,scriptreplay 文件查找:find 提供管道参数:xargs 转换:tr 排序.唯一:sort.uniq 临时文件:mktemp 分割文件和数据:split,cs

Linux Shell系列教程之(七)Shell输出

本文是Linux Shell系列教程的第(七)篇,更多shell教程请看:Linux Shell系列教程 与其他语言一样,Shell中也有输出操作,而且在实际应用中也是非常重要的,今天就为大家介绍下Shell输出操作. Shell echo命令 echo命令是Shell的一个内部指令,用于在屏幕上打印出指定的字符串. 命令格式: echo arg 转义字符 像其他高级语言一样,Shell也使用反斜杠“\”作为转义字符. 例子: echo "\"It is a test\"&q

Linux Shell系列教程之(六)Shell数组

本文是Linux Shell系列教程的第(六)篇,更多shell教程请看:Linux Shell系列教程 Shell在编程方面非常强大,其数组功能也非常的完善,今天就为大家介绍下Shell数组的用法. Shell支持一维数组(不支持多维数组),并且没有限定数组的大小. 类似与C语言,数组元素的下标由0开始编号.获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0. 一.Shell数组的定义 在Shell中,用括号来表示数组,数组元素之间用“空格”分割开. 定义数组的一般形式

Linux Shell常用技巧(八) 系统运行状况

Linux Shell常用技巧(八) 系统运行状况 十八.  和系统运行状况相关的Shell命令:    1.  Linux的实时监测命令(watch):     watch   是一个非常实用的命令,可以帮你实时监测一个命令的运行结果,省得一遍又一遍的手动运行.该命令最为常用的两个选项是-d和-n,其中-n表示间隔多少秒 执行一次"command",-d表示高亮发生变化的位置.下面列举几个在watch中常用的实时监视命令:    /> watch -d -n 1 'who'  

XAMPP(Linux版-x86兼容)官网下载

欢迎光临 XAMPP 的 Linux 版 (x86 兼容处理器版)顺便提一下:该软件以前被称作 LAMPP,但为了避免误解,我们将其重名命为 »XAMPP 的 Linux 版«.所以,如果您在寻找 LAMPP,您就来对地方了.;) 如果你遇到任何有关 XAMPP 的问题,敬请与我们联系.这将帮助我们改进 XAMPP,使其更易于使用. 安装过程仅 4 个步骤 步骤 1:下载 只需点击下面的链接.下载最新版总是好主意.:)完整的下载列表(老版本)可在 SourceForge 找到. 详细的 XAMP

Linux Shell系列教程之(四)Shell注释

本文是Linux Shell系列教程的第(四)篇,更多shell教程请看:Linux Shell系列教程 与许多的编程语言一样,Shell中也有注释符号,今天就为大家来介绍下Shell中的注释的语法及用法. Shell中的注释以“#”号开头,所有以“#”号开头的代码都会被解释器所忽略. 比如下面的代码: #!/bin/bash # Author : linuxdaxue.com # Date : 2016-05-15 echo "What is your name?" read PER

Linux Shell系列教程之(三)Shell变量

本文是Linux Shell系列教程的第(三)篇,更多shell教程请看:Linux Shell系列教程 Shell作为一种高级的脚本类语言,也是支持自定义变量的.今天就为大家介绍下Shell中的变量相关知识. 为使Shell编程更有效,系统提供了一些Shell变量.Shell变量可以保存诸如路径名.文件名或者一个数字这样的变量名. Shell将其中任何设置都看做文本字符串.有两种变量,本地和环境.严格地说可以有 4种,但其余两种是只读的,可以认为是特殊变量,它用于向Shell脚本传递参数. 定