博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用正则获取百度贴吧当日新贴
阅读量:7094 次
发布时间:2019-06-28

本文共 3507 字,大约阅读时间需要 11 分钟。

工作中需要抓百度贴吧指定贴吧每日新贴,包括主题贴和回复贴。

按理说百度应该给吧主提供这样的功能。但我没找到。
百度还提供了个高级搜索功能 http://tieba.baidu.com/f/search/adv 。搜索结果可以按时间倒序排列,可惜必须设关键字或用户名。所以也不能满足需求。
想了个变通的办法。
1)每分钟爬一次首页,取到首页上最后回复者的用户名。
2)使用高级搜索,设定吧名和用户名搜索并提取发贴日期为结果。

[root@iZlmsymZ ~]$wget http://tieba.baidu.com/f?kw=%C9%BD%CE%F7 -O - | grep -Po 'href="(/p/[0-9]{10}).*?j_user_card.*?\>(.*?)\<.*?threadlist_reply_date j_reply_data.*?>[ ]*([0-9]{1,2}:[0-9]{2})' - | sed -r s/'href="(\/p\/[0-9]{10}).*?j_user_card[^>]*>([^<]*)<.*?threadlist_reply_date j_reply_data.*?>[ ]*([0-9]{1,2}:[0-9]{2})'/'\1\t\2\t\3'/g

 

wget -- linux 下获取 http页面的工具 -O - 表示输出到管道(而不是文件)

grep --linux 正则表达式工具

-P  使用 prel语法

-o  只输出匹配到的内容(而不是一行)

(/p/[0-9]{10}) 首页贴子的链接,格式为 a href="/p/3444444444"
.*? 非贪婪匹配任意字符  j_user_card.*?\>(.*?)  查找发贴人昵称,值为(.*?)
threadlist_reply_date j_reply_data.*?>[ ]*([0-9]{1,2}:[0-9]{2})  最后回复日期,值为([0-9]{1,2}:[0-9]{2}) 首页中不能获取到最新回复贴的url。为了获取最新的帖子(无论是主题还是回复),需要以到 http://tieba.baidu.com/f/search/ures? 查询。查询条件是吧名和用户名。在找到的结果中,如果发贴时间匹配,那么就可以认为是刚才在首页查到的新贴,从而采集url.
wget http://tieba.baidu.com/f?kw=山西 -O - | grep -Po 'j_user_card.*?\>.*?\<' - | sed -r s/'j_user_card[^>]*>([^<]*)<'/'http:\/\/tieba\.baidu\.com\/f\/search\/ures\?ie=utf-8\&kw=山西\&un=\1'/g
j_user_card 是用户名所在的标签标识。用grep找到后,用sed提取并连接成url。结果如下:
http://tieba.baidu.com/f/search/ures?ie=utf-8&kw=山西&un=佛光普照五台山http://tieba.baidu.com/f/search/ures?ie=utf-8&kw=山西&un=不见风雨见彩虹http://tieba.baidu.com/f/search/ures?ie=utf-8&kw=山西&un=★冰月寒心★http://tieba.baidu.com/f/search/ures?ie=utf-8&kw=山西&un=小伟苦笑http://tieba.baidu.com/f/search/ures?ie=utf-8&kw=山西&un=小伟苦笑http://tieba.baidu.com/f/search/ures?ie=utf-8&kw=山西&un=领域神王http://tieba.baidu.com/f/search/ures?ie=utf-8&kw=山西&un=chenxin0357 ……

 

[root@iZ62jhlmZ ~]$wget http://tieba.baidu.com/f?kw=山西 -O - | grep -Po 'j_user_card.*?\>.*?\<' - | sed -r s/'j_user_card.*?>([^<]*)<'/'\/f\/search\/ures\?ie=utf-8\&kw=山西\&un=\1'/g | wget --base=http://tieba.baidu.com -i - -O - | grep -Po '
' >urlcheck.txt

 

上面使用 "wget -i - -O -"打开sed 组织的url,并使用grep提取相关内容到 urlcheck.txt中。 

 

 

grep -Po '
'

在高级查询中查询到的记录,我们只取当天的。

[root@iZ62jhlmsZ ~]$grep "$(date --rfc-3339='date')"

 所以,提取一个用户当天发贴的语句是:

wget http://tieba.baidu.com/f?kw=山西 -O - | grep -Po 'j_user_card.*?\>.*?\<' - | sed -r s/'j_user_card.*?>([^<]*)<'/'\/f\/search\/ures\?ie=utf-8\&kw=山西\&un=\1'/g | wget --base=http://tieba.baidu.com -i - -O - | grep -Po "
.*?
$(date --rfc-3339='date').*?<\/font>" |  sed s/'^.*
\(.*\)<\/a>.*
\(.*\)<\/div>.*
\(.*\)<\/font>.*
.*\([-0-9: ]\{16\}\)<\/font>.*$'/'\1\t\2\t\3\t\4\t\5'/g

 实际sed操作会出错,试着转成utf-8编码就正常了。

iconv --from-code=latin1 --to-code=utf-8

原因解释:

"sed的执行会和locale相关。比如说如果文件的编码是gbk的,而locale是utf-8,这时候你所有关于正则表达式的知识都是不起作用的。根据我的经验用sed处理有中文字符处理的文件,最好把locale设置成LC_ALL=C,进行处理,或者你能保证文件的编码和locale是一致的情况下。" 

export LC_ALL=C

推荐使用 LC_ALL=C 因为转成utf-8会严重影响正则匹配的效率。

sed 的另一个问题是它不支持非贪婪匹配。所以在书写的时候费了很大周折。

另外还得删除重复的记录。

awk '!a[$0]{a[$0]=1;print  "/f/search/ures?rn=10&ie=utf-8&kw=山西&un="$0}' ./tiebaapp/tiebaactiveuser.lst&& :>./tiebaapp/tiebaactiveuser.lst |  wget -q  --base=http://tieba.baidu.com -i - -O - | grep -Po "
.*?
$(date --rfc-3339='date').*?<\/font>" | iconv --from-code=latin1 --to-code=utf-8 | sed s/'^.*
\(.*\)<\/a>.*
\(.*\)<\/div>.*
\(.*\)<\/font>.*
.*\([-0-9: ]\{16\}\)<\/font>.*$'/'\1\t\2\t\3\t\4\t\5'/g

转载于:https://www.cnblogs.com/diylab/p/4228632.html

你可能感兴趣的文章
Hadoop Streaming框架使用(二)
查看>>
网站升级2.0回滚机制
查看>>
centos6.9 网络配置,防火墙,复制虚拟机20180127
查看>>
h3c防火墙的设置过程
查看>>
KMP + 求最小循环节 --- HUST 1010 - The Minimum Length
查看>>
<从优秀到卓越>读书笔记
查看>>
Python3 序列解包
查看>>
C/C++ —语言判断数字或字符的函数总结
查看>>
ParentalControl-SteadyState
查看>>
设计模式 — 结构型模式 适配器模式
查看>>
Tempter of the Bone------剪枝
查看>>
Java学习笔记---IO操作
查看>>
Hadoop2
查看>>
"Chinese Pinyin"App-隐私政策
查看>>
java多态性,父类引用指向子类对象
查看>>
机器学习入门03 - 降低损失 (Reducing Loss)
查看>>
Material Design(七)--Snackbar
查看>>
文件MD5
查看>>
收集的博客网址springboot、cloud
查看>>
解析函數論 Page 29 命題(3) 模的下界的可達性
查看>>