哎呀哎呀,开学後变得好忙阿,连一天写一篇的时间都没有,果然先预留点文章是对的。参赛前还以为30天很短,实际参赛後才觉得真的是很漫长的过程,离结束还剩12天,好久阿~ (茶
好啦,发牢骚就到这边,昨天我们已经用session抓到PTT八卦板的文章清单了,今天就接续来说怎麽抓到每一篇文的作者等详细资讯吧!
我们延续昨天的进度,已经可以抓到首页的文章列表了,但问题是,首页能得到的资讯最多就这样了,如果还想要进一步抓到文章中作者、时间等资讯该怎麽办呢?
因此我们要另外想办法,一样 右键>>检查,会观察到标题其实就是个连结<a>
,而连结中的属性href
正是文章内页的网址。
既然这样,就只需要我们之前学过BeautifulSoup的find_all()
就OK了。
import requests
from bs4 import BeautifulSoup
# post要传的资料
payload = {
'from': '/bbs/Gossiping/index.html',
'yes': 'yes'
}
# 用session纪录此次使用的cookie
rs = requests.session()
# post传递资料
response = rs.post("https://www.ptt.cc/ask/over18", data=payload)
# 再get一次PTT八卦板首页
response = rs.get("https://www.ptt.cc/bbs/Gossiping/index.html")
print(response.status_code)
root = BeautifulSoup(response.text, "html.parser")
links = root.find_all("div", class_="title") # 文章标题
for link in links:
print(link.a["href"])
执行的结果:
但抓到的网址并不是完整的网址,我们要在前面加上PTT的网域才行。
for link in links:
page_url = "https://www.ptt.cc"+link.a["href"]
print(page_url)
这样就可以顺利取得文章内文的连结了!
那麽,取得这些连结後又要干嘛呢? 当然就是利用这些网址,去取得每篇文章内文的原始码阿! 取得方法更前面取得首页文章列表类似,方法同样是用GET。
用先前建立好的session物件,就不需要再带cookie罗! 原因请见Day17。
response = rs.get(page_url)
result = BeautifulSoup(response.text, "html.parser")
随便打开一篇文章,检查作者、标题、时间这些栏位是放在哪里。
发现都在 class="main-content"
的div底下 class="article-meta-value"
的span中。
所以程序码就:
main_content = result.find("div", id="main-content")
article_info = main_content.find_all("span", class_="article-meta-value")
if len(article_info) != 0:
author = article_info[0].string # 作者
title = article_info[2].string # 标题
time = article_info[3].string # 时间
else: # 避免有没有资讯的状况
author = "无" # 作者
title = "无" # 标题
time = "无" # 时间
因为class="article-meta-value"
的span有4个,但,第一个是作者,第二个是我们不想要的,第三个的是标题,第四个是时间,所以索引值就是0、2、3。
老样子,文章内容>>右键>>检查,但这次有点麻烦,内容不存在特定的容器中。只是单纯的丢到 "main-content" 而已。
即使如此也难不倒我们! 多检查几篇不同文章後,就会发现文章都是以 "- -" 来做结尾的,我们就来利用这个特性。
把先前抓的 "main_content" 文字的部分(text),使用split("- -")
以 "- -" 符号分割字串,并把最後一段给舍弃(通常是其他不相关的内容)。
但因为原本文章可能也含有 "- -" 符号而不小心被切割,再用 join()
函数将字串恢复原样。
# 将整段文字内容抓出来
all_text = main_content.text
# 以--切割,抓最後一个--前的所有内容
pre_texts = all_text.split("--")[:-1]
# 将前面的所有内容合并成一个
one_text = "--".join(pre_texts)
试着把目前的文章内容print出来检查。
发现文章是从第一个换行後开始(第一行是作者资讯那些的),所以就用 "\n" 来做分割,更上面一样,用 join()
函数将字串恢复原样。
# 以\n切割,第一行标题不要
texts = one_text.split("\n")[1:]
# 将每一行合并
content = "\n".join(texts)
结果,非常完美www (灿笑
今天教到怎麽抓取PTT八卦板文章的作者资讯和内容,明天接续来处理留言串的部分,还有最後把爬到的资料整理汇出成JSON档,就这样吧!
今天的文章好像有点划水,但最近真的比较忙,接下来会尽量每天多空出时间来写文章的。
写文章的此刻,网路上正好流行肥宅对话的话题,所以PTT上面出现很多相关的讨论串,为了让文章有趣一点,我也在文章里加了一点肥宅用语(没有很多啦),希望读者看了之後没有感到很不舒服www (摸头
如果喜欢这系列文章麻烦帮我按Like加订阅,你的支持是我创作最大的动力~
本系列文章以及范例程序码都同步更新在GitHub上,後续会持续的更新,如果喜欢也麻烦帮我按个星星吧~
有任何问题或建议,都欢迎在底下留言区提出,还请大家多多指教。
添加中文字体 在安装matplotlib後,因为我们的资料内含有中文字,而matplotlib内建并...
上篇介绍了如何将档案 Push 到 GitHub 後,今天就来练习如何从 GitHub 下载档案吧!...
昨天我们说到刷新tableview的部分,因为每一笔资料写入都要将资料写进realm里,再从中回传至...
The future is already here – it's just not evenly...
在前几篇我们介绍了 Docker 以及 Docker Compose,让开发时的环境设定不会再因为作...