嗨大家,今天我們要來說明如何爬ptt的文章啦!只需要用requests
&beautifulSoup
就行啦!
(關於此內容會拆分成兩天說明哦!)
在開始爬取一個網站之前一定要觀察該網頁的變化:
這次我們以爬美食板為例(下圖):
https://www.ptt.cc/bbs/<看板名稱>/index.html
右鍵>檢查
,可以看到該文章標題與href
,而href
就是我們需要的內容。如下圖可以看出它在<a>
標籤內且被<div class="title"></div>
包覆。href
呢?點進去可以發現href就是文章的連結(如圖):好了之後就開始寫程式碼吧!
list
變數article_href
。<a>
標籤在<div class="title"></div>
,用select
取得所有div
且class="title"
的物件import requests
from bs4 import BeautifulSoup
article_href = []
r = requests.get("https://www.ptt.cc/bbs/Food/index.html")
soup = BeautifulSoup(r.text,"html.parser")
results = soup.select("div.title")
print(results)
應該會得到以下結果:是一個list
,裡面把該頁的div class="title"
元素都取出來且裡面包覆著<a>
標籤。
[<div class="title">
<a href="/bbs/Food/M.1540099186.A.315.html">[食記] 高雄岡山羊肉 - 舊市羊肉</a>
</div>, <div class="title">
<a href="/bbs/Food/M.1540104279.A.FDB.html">[食記] 蘆洲 Tiffany綠 98 nine eight land</a>
</div>, <div class="title">
(略)
<div class="title">
<a href="/bbs/Food/M.1535474674.A.9D5.html">Fw: [公告] 報考小天使資格及注意事項</a>
</div>]
我們知道results
為一個list
for item in results:
item_href = item.select_one("a").get("href")
article_href.append(item_href)
print(article_href)
# ['/bbs/Food/M.1540099186.A.315.html',
# '/bbs/Food/M.1540104279.A.FDB.html',
# '/bbs/Food/M.1540106895.A.744.html',
# '/bbs/Food/M.1540107608.A.D43.html',
# '/bbs/Food/M.1540109077.A.62C.html',
# '/bbs/Food/M.1540110023.A.39A.html',
# '/bbs/Food/M.1355673582.A.5F7.html',
# '/bbs/Food/M.1190944426.A.E6C.html',
# '/bbs/Food/M.1128132666.A.0FD.html',
# '/bbs/Food/M.1496532469.A.C36.html',
# '/bbs/Food/M.1535474674.A.9D5.html']
這樣就取到該頁的所有連結了,不過這樣的話只有取到第一頁的文章,所以現在我們來看看如何切頁吧!
右上角有一個<上頁
的按鈕,對它點擊右鍵>檢查
:
一樣可以看到href
,這個就是我們要切換頁面的連結,接下來要做的就是抓到它!
div
內class
為btn-group
下的a
標籤btn = soup.select('div.btn-group > a')
up_page_href = btn[3]['href']
next_page_url = 'https://www.ptt.cc' + up_page_href
print(next_page_url)
# https://www.ptt.cc/bbs/Food/index6958.html
我們可以用for迴圈
定義要抓幾頁:
url="https://www.ptt.cc/bbs/Food/index.html"
for page in range(1,4):
r = requests.get(url)
soup = BeautifulSoup(r.text,"html.parser")
btn = soup.select('div.btn-group > a')
up_page_href = btn[3]['href']
next_page_url = 'https://www.ptt.cc' + up_page_href
url = next_page_url
print(url)
最後整理一下,寫成這樣(本篇的完整程式碼):
import requests
from bs4 import BeautifulSoup
url="https://www.ptt.cc/bbs/Food/index.html"
def get_all_href(url):
r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")
results = soup.select("div.title")
for item in results:
a_item = item.select_one("a")
title = item.text
if a_item:
print(title, 'https://www.ptt.cc'+ a_item.get('href'))
for page in range(1,4):
r = requests.get(url)
soup = BeautifulSoup(r.text,"html.parser")
btn = soup.select('div.btn-group > a')
up_page_href = btn[3]['href']
next_page_url = 'https://www.ptt.cc' + up_page_href
url = next_page_url
get_all_href(url = url)
比較不同的是:
get_all_href()
function,用來抓取每一頁的所有文章連結if a_item:
是因為可能會有文章刪除或不存在的可能,會得到None
,所以需要先確認a_item
是有值的,我們才取href
。如上圖,就可以看到我們抓了三頁的文章標題以及它的連結,是不是很簡單呢?那今天就到這裡了,明天將繼續說明如何再往裡面抓取文章的內容等資訊以及如何抓取圖片哦!
如果有問題歡迎留言告訴我,最近真的忙到昏了很擔心文章會有誤(塊陶~)
不好意思,又來請教了~請問一下,在這篇中用 'div.btn-group > a' 來選取上頁的網址,那和上一篇中使用空格的方式來選取如 'div.btn-group a' 有什麼不一樣呢?是否能舉個實例說明這兩個語法上的不同之處?謝謝!
用>
的話,是只要下一層的哦!
噢~我懂了~謝謝~
請問這是用程式撰寫的
請問在後面跑迴圈的時候原先的 URL不是已經被next_page_url改寫,那在最後call get_all_href(url = url),怎麼不是先爬上頁的內容呢
更新一下,自己跑一次後發現這次跑的程式碼,好像真的會少主頁的內容,直接從上頁開始跑