嗨,第八天了!昨天介紹了網頁HTML
的架構,今天就要來說明如何用BeautifulSoup
去解析裡面的內容。BeautifulSoup
在上一年的鐵人賽我有簡單的說明過了。
那今天要說什麼呢?我們就來解析昨天Google搜尋畫面的內容吧!
import requests
from bs4 import BeautifulSoup
r = requests.get('https://www.google.com/search?q=python3')
soup = BeautifulSoup(r.text, 'lxml')
requests
, BeautifulSoup
https://www.google.com/search?q=python3
為我們要請求的網址,這個頁面為我們在Google搜尋python3
出來的頁面(可以看昨天的文章)BeautifulSoup
。在昨天的文章中,我們關閉了JS,關閉之後會看到這個畫面:
現在來看看裡面的元素吧,先從標題點右鍵檢查:
可以看出它在a
標籤裡面,但若我們直接抓取所有a
標籤,會把葉庫存檔
,類似內容
等內容也抓到,所以我們往上一層看,會發現a
包覆在h3
且class
為r
的標籤裡面,程式碼:
a_tags = soup.select('h3.r a')
for t in a_tags:
print(t.text)
可以看出我們找到所有的標題了:
來說明一下select()
也就是css 選擇器,若有寫過css
就能夠理解怎麼去解析它,.
&#
的用法就是css在用的寫法。其實select()
就跟find_all()
是一樣的,只是內容的寫法不同,find_all()
在上一年文章已經說明過了,這裡就不贅述了,.select('h3.r a')
中的h3
為標籤名稱.
為class
屬性,所以.
後面接class名稱
也就是r
,#
為 id
屬性。
select()
所得到的內容為一list
,跟find_all()
一樣,所以若確定只有一個內容可以用select_one()
。title = soup.select_one('h3.r a')
print(title.text)
上面程式碼,只會得到Python 3.0 Release | Python.org
。
title.text
。這樣有理解兩個的差別了嗎?
接下來我們來取得href
吧!先來看看a_tag
這個變數是什麼內容:
a_tag = soup.select_one('h3.r a')
print(a_tag)
# <a href="/url?q=https://www.python.org/download/releases/3.0/&sa=U&ved=0ahUKEwigs7is6PvdAhXB2LwKHSUqCWoQFggTMAA&usg=AOvVaw0PrtXxN9eChI2u0SKQ7wuS">Python 3.0 Release | Python.org</a>
可以看出來它抓到整個a
元素的內容,那href
要怎麼得到呢?
print(a_tag['href'])
# /url?q=https://www.python.org/download/releases/3.0/&sa=U&ved=0ahUKEwjo9qPw6PvdAhVV6bwKHQVBDrAQFggTMAA&usg=AOvVaw1-sMTCID-cyLCuxL9Q4fIU
好的,現在得到了這串不知名的href
要做什麼呢?
a_tag = soup.select_one('h3.r a')
href = a_tag['href']
googleUrl = 'https://www.google.com'
print(googleUrl + href)
# https://www.google.com/url?q=https://www.python.org/download/releases/3.0/&sa=U&ved=0ahUKEwiBkavx6fvdAhXIvLwKHVstDacQFggTMAA&usg=AOvVaw0qRzzs3ItQQZszDNvtFiet
所得到的內容就是搜尋結果的第一個網頁連結了!不信的話點進去看看?
最後,我們寫一個小小的範例,抓到href
後重新更換url
重新requests
,並將頁面存到html
檔案內:
r = requests.get('https://www.google.com/search?q=python3')
soup = BeautifulSoup(r.text, 'lxml')
googleUrl = 'https://www.google.com'
a_list = soup.select('h3.r a')
for a in a_list:
print('title', a.text)
print('href', a['href'])
contentUrl = googleUrl + a['href']
r = requests.get(contentUrl)
with open ( a.text + '.html', 'w+') as f:
f.write(r.text)
print('saved')
這樣我們就得到每個連結裡的網頁內容了!
透過這個方式我們可以再分別解析網頁內容!
因此,明天我們來試試看如何透過requests
&BeautifalSoup
爬PTT!
最下面的範例沒有提供 headers 呦...
另外我想問一下,如果 javascript 沒有關掉的話,抓到的網頁會是長的如何?
我用 stackoverflow 提供的解答,用 developer 的工具把 javascript 濾掉,不知道這樣的方法,和你所說的是否有同樣的效果呢? https://stackoverflow.com/questions/13405383/how-to-disable-javascript-in-chrome-developer-tools
你好,
其實在上面程式碼中可以不需要加入header
參數,直接
r = requests.get(contentUrl)
我文章會再修正一下,感謝你。
或是header
設定像是:headers={'Content-type': 'text/plain; charset=utf-8'}
關於你提到如果javascript沒有關掉的話,抓到的網頁會是長的如何?
的問題,
應該要這樣解釋:
我之所以要示範關閉javascript
(第7天),
是因為爬蟲抓到的就是沒有js
的內容,除非用工具渲染js(後面文章有提到)不是說因為我們關閉了所以才只會抓到沒有js的內容(有點饒舌)
你上面網址的內容,我在第7天有說明哦https://ithelp.ithome.com.tw/articles/10204082
謝謝...我還是有點看不懂 js 的部分,或許看到後面的時候再來請教吧!