在這之前呢,希望大家可以把HTML語法再複習一次,
如果還不會HTML的語法的話,建議可以到以下網站去練習一下,
https://www.codecademy.com/learn/all
只要練習有關HTML的課程就好,如果對CSS有興趣的話往後可以再深究,
假如還不太熟悉Python語法的話也可以到上面的網站進行練習唷!
Step 1. 安裝相關套件
假如在Ubuntu上使用的話,要先用pip安裝這三個套件requests、beautifulsoup、lxml,
pip install requests
pip install beautifulsoup4
pip install lxml
pip install beautifulsoup4
pip install lxml
先解說一下這三個的功用:
2. BeautifulSoup 是用來分析與抓取HTML中的元素
3. lxml 讓解析HTML可以變得更快
若在Windows上的話可以安裝 Anaconda,
使用Anaconda中的Jupyter notebook可以不用特別安裝上面那兩樣東西。
Step 2. 瀏覽要擷取的網頁
我們隨便選了一篇在電影版上的文章(看你想擷取哪一篇),
我選了一篇爆的文章,因為這樣留言數才會多,之後想分析的話會比較好分析XD
要擷取的網址大概會長這樣:
https://wwwtt.cc/bbs/movie/M.1496375334.A.C6B.html
灰色的部分呢是PTT電影版的文章列表(記得要把紫色部分改成index),
而紫色的部分是每篇文章特有的index。
Step 3. 開始撰寫程式
我們先import剛剛安裝的那兩個套件,而import有點像是C語言中的include,
而這邊比較特殊的是BeautifulSoup,它要先from bs4在import,
import requests
from bs4 import BeautifulSoup
from bs4 import BeautifulSoup
在設定一個變數 url 來存放要擷取的網站,
之後我們會使用 requests.get() 這個函式,仿造HTTP的GET來瀏覽網站,
其目的主要是要取得此網站的原始碼,
我們取得之後可以將它印出,
#所要擷取的網站網址
url = '自行選取想要的電影版網址'
#建立回應
response = requests.get(url)
#印出
print(response.text)
url = '自行選取想要的電影版網址'
#建立回應
response = requests.get(url)
#印出
print(response.text)
印出的內容大概會長這樣:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title> 其文章標題 - 看板 movie - 批踢踢實業坊</title> <meta name="robots" content="all"> <meta name="keywords" content="Ptt BBS 批踢踢"> <meta name="description" content="內文">
-----------------------------------(以下省略)------------------------------
取得原始碼後我們要將它做整理!
接著我們可以透過 (F12 開發者工具)來觀察網站的留言到底會放在哪個地方,
我們會發現其留言會放在 class = "push" 的 div 標籤中,
因為HTML的語法屬於階層式,它會把東西放在一層又一層的標籤裡,
因此我們需要一層一層的去了解其資料是放在哪一層,
這裡我們會使用到find_all()的方法來操作BeautifulSoup來找特定目標(也就是push),
#將原始碼做整理
soup = BeautifulSoup(response.text, 'lxml')
#使用find_all()找尋特定目標
articles = soup.find_all('div', 'push')
#印出
print(articles)
soup = BeautifulSoup(response.text, 'lxml')
#使用find_all()找尋特定目標
articles = soup.find_all('div', 'push')
#印出
print(articles)
其印出的內容為 class = "push" 的 div 標籤中所有的東西,
包括推、噓、ID、留言、推文時間等,印出的結果如下:
[<div class="push"><span class="hl push-tag">推 </span><span class="f3 hl push-userid">yang560831</span><span class="f3 push-content">: 都不用爭執 10分鐘後我在這帖一次爆光光</span><span class="push-ipdatetime"> 06/02 11:50
-----------------------------------(以下省略)------------------------------
因為我們是要擷取留言,而留言它是放在 class = "f3 push-content"的 span 標籤裡,
只要把它從這邊撈出來基本上就大功告成了!
#取得留言內容
for article in articles:
messages = article.find('span', 'f3 push-content').getText()
print(messages)
for article in articles:
messages = article.find('span', 'f3 push-content').getText()
print(messages)
印出結果如下:
撈出來後會發現前面會多個冒號,
我們可以用replace()這個方法來去除掉冒號,
但去除掉之後還是會有空格怎麼辦?
這時候我們可以使用strip()來去除左右的空白格,
這樣就算大功告成了!
之後我們可以把它寫進txt或pickle中,
這樣就不用再每次去爬它了,也不用擔心資料會流失,
其完整程式碼如下:
import requests
from bs4 import BeautifulSoup
#所要擷取的網站網址
url = '自行選取想要的電影版網址'
#建立回應
response = requests.get(url)
#印出網站原始碼
#print(response.text)
#將原始碼做整理
soup = BeautifulSoup(response.text, 'lxml')
#使用find_all()找尋特定目標
articles = soup.find_all('div', 'push')
#寫入檔案中
with open('movie_message.txt','w') as f:
for article in articles:
#去除掉冒號和左右的空白
messages = article.find('span','f3 push-content').getText().replace(':','').strip()
print(messages)
f.write(messages + "\n")
from bs4 import BeautifulSoup
#所要擷取的網站網址
url = '自行選取想要的電影版網址'
#建立回應
response = requests.get(url)
#印出網站原始碼
#print(response.text)
#將原始碼做整理
soup = BeautifulSoup(response.text, 'lxml')
#使用find_all()找尋特定目標
articles = soup.find_all('div', 'push')
#寫入檔案中
with open('movie_message.txt','w') as f:
for article in articles:
#去除掉冒號和左右的空白
messages = article.find('span','f3 push-content').getText().replace(':','').strip()
print(messages)
f.write(messages + "\n")
Reference:
[1] https://github.com/leVirve/CrawlerTutorial
[2] Beautiful Soup Documentation,
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
[3] Requests,http://docs.python-requests.org/en/master/
[4] PTT 電影版, https://www.ptt.cc/bbs/movie/index.html
[5] Python Cookbook 3rd Edition Documentation,
http://python3-cookbook.readthedocs.io/zh_CN/latest/index.html
如有疑問歡迎在下方留言告訴我唷~~~
請問如果只要內文的部分要如何抓
回覆刪除import requests
刪除from bs4 import BeautifulSoup
#所要擷取的網站網址
url = 'https://www.ptt.cc/bbs/movie/M.1496375334.A.C6B.html'
#建立回應
response = requests.get(url)
def checkformat(soup, class_tag, data, index, url):
content = soup.select(class_tag)[index].text
return content
date = checkformat(soup, '.article-meta-value', 'date', 3, url)
#將原始碼做整理
soup = BeautifulSoup(response.text, 'lxml')
#content 文章內文
content = soup.find(id="main-content").text
target_content = u'※ 發信站: 批踢踢實業坊(ptt.cc),'
#去除掉 target_content
content = content.split(target_content)
#print(content)
content = content[0].split(date)
#print(content)
#去除掉文末 --
main_content = content[1].replace('--', '')
#印出內文
print(main_content)
上面checkformat的部分要記得縮排一下
刪除留言縮排好像會被吃掉...
謝謝你解決我的問題
刪除同上, 也想請教大大在html中沒有被tag包住的內文跟作者修文置於留言間的回應要怎麼抓比較方便呢QQ?
回覆刪除這部分我沒試過耶 哈哈
刪除我有空再研究好了 你先試試看目前我改的程式碼
可以抓取內文了
我自己有試出一個方法,是用bs4的type類型去篩,因為如果是頁面上單純的白字的話,type會跟有tag的不一樣,所以我用if str(type(...)) ...去篩出白字內容。但缺點是如果內文有上色之類的話在html中就會有tag,所以這方法只適用抓取未經任何處理的白字部分XD 目前在抓內文上也是參考python板用切的,應該跟你差不多ww
刪除你好, 想請問抓完留言怎麼把同帳號的留言合併 ? 謝謝
回覆刪除