爬取 LINE TODAY 留言
这篇文章会解析 LINE TODAY 的留言页面,搭配 Python 的 Requests 函数库,实作一个可以爬取 LINE Today 某篇文章所有留言的网络爬虫。
本篇使用的 Python 版本为 3.7.12,所有范例可使用 Google Colab 实作,不用安装任何软件 ( 参考:使用 Google Colab )
LINE Today 留言结构
使用 Chrome 浏览器,打开 LINE TODAY 的页面,点选任意一篇文章,打开文章页面。
LINE TODAY:https://today.line.me/tw/v2/tab
本篇范例打开了一篇“英特尔基辛格已抵台 录影片赞声台积电”的文章。
将文章往下卷动,找到留言的位置,点击“显示全部”,会打开留言的页面。
文章对应的留言页面:https://today.line.me/tw/v2/comment/article/oqay0ro
打开留言页面后,在网页的任意位置,按下鼠标右键,点击“检视”,打开 Chrome 开发者工具,切换到“Network”页签,在 Network 页签里,可以看到网页打开时,所有透过网络下载或上传的内容 ( 如果没有看到内容,重新整理网页就会看到 )。
点击前方的清除按钮,清空内容 ( 方便待会观察出现哪些项目 ),再将子页签切换到“Fetch/XHR”,该页签表示有哪些 XMLHttpRequest 对象在交换沟通。
重新整理网页,开发者工具中就会陆续出现一些对象,在画面里找到名为“list?articleId=.....”的项目,点选这个项目,就能看到该文章的有多少留言以及所有留言的内容。
观察一下这个对象的网址 ( 可以在该项目上按下鼠标右键,打开到新的 tab 里 ),可先注意这篇文章的 articleId、每次显示留言的数量 limit 和第二页开始的次序 pivot。
https://today.line.me/webapi/interaction/comment/list?articleId=179673305&country=TW&postId=179673305&postType=Article&sort=POPULAR&direction=DESC&limit=30&pivot=0
因为留言对象的网址数量 limit 设定为 30,所以如果该网页的留言很多 ( 范例网页有超过两百则留言 ),会产生“不止一笔”留言对象,这时从开发者工具里就会看到 pivot=0、pivot=30、pivot=60...等的留言对象网址。
由于文章的网址并没有 articleId,表示网页一定是透过某些机制将网址对应到 articleId,检视网页源代码后 ( 在网页上点击鼠标右键,点选检视网页源代码 ),搜索 179673305 ( 这篇文章的 articleId ),会发现网页源代码有撰写了相对应的转换程序,如何转换并不重要,重要的是记住下图标注红色的位置,待会会透过程序截取对应的 articleId。
转换网址,印出留言总数
由于 Fetch/XHR 的网址使用的是 articleId,所以必须先从原本的网址里提取 articleId ( 目的在于如果有多个页面,就不用一一打开开发者工具找 articleId ),下方的程序码执行后,会印出该篇文章的 articleId。
import requests
webUrl = requests.get('https://today.line.me/tw/v2/article/oqay0ro') # get 文章網址
# 取得文章的原始碼後,使用 split 字串拆分的方式,拆解出 articleId
article_id = webUrl.text.split('<script>')[1].split('id:"article:')[1].split(':')[0]
print(article_id)
取得 articleId 后,将使用变数与字串格式化的方式,将留言对象的 articleId 更换成该篇文章的 articleId,再度使用 requests,取得 json 格式的内容,并印出文章的总数。
import requests
webUrl = requests.get('https://today.line.me/tw/v2/article/oqay0ro') # get 文章網址
# 取得文章的原始碼後,使用 split 字串拆分的方式,拆解出 articleId
article_id = webUrl.text.split('<script>')[1].split('id:"article:')[1].split(':')[0]
print(article_id)
# 使用 requests get 留言物件
commentUrl = requests.get(f'https://today.line.me/webapi/interaction/comment/list?articleId={article_id}&country=TW&postId={article_id}&postType=Article&sort=POPULAR&direction=DESC&limit=30&pivot=0')
json = commentUrl.json()
num = int(json['count'])
print(num) # 印出文章總數
印出每一笔留言的内容
由于留言笔数过多时 ( 每页留言一次显示最多 100 篇 ),留言的对象会拆分成不同的项目,所以下方的程序定义了一个 getComment 函数,在函数执行时赋予“pivot”( 下一页从第几笔留言开始 ) 的参数,并透过 range 和 for 循环的搭配,就能印出所有的留言。
import requests
webUrl = requests.get('https://today.line.me/tw/v2/article/oqay0ro')
article_id = webUrl.text.split('<script>')[1].split('id:"article:')[1].split(':')[0]
print(article_id)
commentUrl = requests.get(f'https://today.line.me/webapi/interaction/comment/list?articleId={article_id}&country=TW&postId={article_id}&postType=Article&sort=POPULAR&direction=DESC&limit=30&pivot=0')
json = commentUrl.json()
num = int(json['count'])
print(num)
for i in json['comments']:
try:
name = i['displayName'] # 有名稱就印出名稱
except:
name = '???' # 沒有名稱就印出問號
print('<' + name + '>\n' + i['contents'][0]['extData']['content'])
小结
一个网页在显示的过程中,背后可能不断的在与后端交换数据,只要善用 Chrome 的开发者工具,可以从中获得很多在网页上看不到的内容,搭配 Python 的函数库,就能轻松抓取各种网页内容了。
微信扫码关注
抖音扫码关注