AndyChiang
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
--- title: 社群網路爬蟲實作課程 # 簡報的名稱 tags: 專題 # 簡報的標籤 slideOptions: # 簡報相關的設定 transition: 'slide' # 換頁動畫 # spotlight: # enabled: true --- # 社群網路爬蟲實作課 --- #### 講者:資工三 江尚軒 --- ## What is 爬蟲? ![](https://i.imgur.com/9LFv0kB.png =40%x) ![](https://i.imgur.com/IMGKK6l.jpg =25%x) > 爬蟲(web crawler) - 是一種自動化瀏覽網頁的機器人 --- ## Why 爬蟲? ![](https://i.imgur.com/CNk6LGS.png =45%x) <!-- 有時資料量可是幾百萬筆起跳的,手動抓會抓到發瘋 --> --- ## Who 爬蟲? * 訓練機器學習之人員 * 股票分析人員 * 市場分析人員 --- ## How 爬蟲? --- ## 1. 首先,我們還要知道網頁長什麼樣子。 --- #### HTML簡介 ---- ### HTML(Hypertext Markup Language) HTML 就像網頁的骨架,決定網頁的組織架構以及呈現內容。 HTML 包含了一系列的元素(elements),而元素包含了標籤(tags)與內容(content)。 ---- ### 元素組成 ![](https://i.imgur.com/x7X1TRF.png) 1. Opening tag: 起始標籤,<>內放入標籤名稱。 2. Closing tag: 結尾標籤,<>內放入和起始標籤一致的標籤名稱,而且要在名稱前加上/符號。 3. Content: 標籤內容。 ---- ### 屬性 ![](https://i.imgur.com/9IBJo4j.png) 屬性可以為元素提供更多資訊,ex: 字型、顏色等等...。 格式為: `屬性名稱 = 屬性值` 而class是將標籤分類(就想成放在同一個箱子裡),之後爬蟲經常會用到。 ---- ### HTML架構 ```htmlmixed= <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>my first html</title> </head> <body> <p>Hello, HTML!</p> </body> </html> ``` 1. `<head>`: 標頭,包含網頁的基本設置,不會顯示在畫面上,ex: 網頁標題、字元實體集...。 2. `<body>`: 包含了所有會顯示於網頁瀏覽者眼前的內容,ex: 段落、圖片...。 ---- ### 看起來... ![](https://i.imgur.com/W5JKock.jpg) ---- ### 基本元素介紹 #### `<h1>~<h6>` 標題,一共有六層,字體從大到小,通常用於文章標題與副標題。 ```htmlmixed= <h1>This is heading1</h1> <h2>This is heading2</h2> <h3>This is heading3</h3> <h4>This is heading4</h4> <h5>This is heading5</h5> <h6>This is heading6</h6> ``` ---- <h1>This is heading1</h1> <h2>This is heading2</h2> <h3>This is heading3</h3> <h4>This is heading4</h4> <h5>This is heading5</h5> <h6>This is heading6</h6> ---- #### `<p>` 段落,通常用於文字內容。 ```htmlmixed= <p> 超文本標記語言(英語:HyperText Markup Language, 簡稱:HTML)是一種用於建立網頁的標準標記語言。 HTML是一種基礎技術,常與CSS、JavaScript一起被眾多網站 用於設計網頁、網頁應用程式以及行動應用程式的使用者介面[3]。 網頁瀏覽器可以讀取HTML檔案,並將其彩現成視覺化網頁。 HTML描述了一個網站的結構語意隨著線索的呈現, 使之成為一種標記語言而非程式語言。 </p> ``` ---- <p> 超文本標記語言(英語:HyperText Markup Language, 簡稱:HTML)是一種用於建立網頁的標準標記語言。 HTML是一種基礎技術,常與CSS、JavaScript一起被眾多網站 用於設計網頁、網頁應用程式以及行動應用程式的使用者介面[3]。 網頁瀏覽器可以讀取HTML檔案,並將其彩現成視覺化網頁。 HTML描述了一個網站的結構語意隨著線索的呈現, 使之成為一種標記語言而非程式語言。 </p> ---- #### `<a>` 超連結,用於連結其他網址,href屬性加上連結網址。 ```htmlmixed= <a href="https://www.nchu.edu.tw/index1.php">中興大學首頁</a> ``` ---- <a href="https://www.nchu.edu.tw/index1.php">中興大學首頁</a> ---- #### `<div>` 區塊,就是一個空的容器,可以在區塊中加入其他元素。 ```htmlembedded= <div style="background-color:blue; color:white; width:400px; height:200px;"> <p>inside the div</p> </div> ``` ---- <div style="background-color:blue; color:white; width:400px; height:200px;"> <p>inside the div</p> </div> ---- #### `<span>` 文字的區塊,包住文字並提供更多資訊。 ```htmlembedded= <p>this color is <span style="color: yellow;">yellow</span></p> ``` ---- <p>this color is <span style="color: yellow;">yellow</span></p> <!-- last page of ch1 --> --- ## 2. 再來,我們得先知道網頁的運作方式。 --- #### request和response的機制 ---- ![](https://i.imgur.com/KbjaM94.png =80%x) 我們就是用戶端(Client),當我們點一個網頁時,就等於向存放該網頁的伺服器(Server)送出請求(Request),當伺服器接收到我們的請求後,就會回傳網頁的內容回來,這就是回應(Response)。 ---- ### 感覺很複雜嗎? 其實網路運作方式就跟去餐廳點餐的流程非常相似,我自己當作用戶端(Client),餐廳老闆當作伺服器(Server)。 ![](https://i.imgur.com/jsvqtfX.png) ---- 當我們進到一間餐廳看著菜單,就像在瀏覽器上瀏覽眾多的網頁。 接著,到櫃檯向老闆點餐,就像是看到喜歡的網頁,發出請求(Request)給伺服端(Server)想看的網頁。 最後,等待老闆烹飪完成送到餐桌上,像是伺服端(Server)端將回應(Response)回傳給用戶端(Client)。 <!-- last page of ch2 --> --- ## 3. OK,那可以開始爬蟲了吧? --- #### requests和BeautifulSoup套件介紹 ---- #### 本文以[PTT八卦版](https://www.ptt.cc/bbs/Gossiping/index.html)為例,教會你如何爬蟲。 ---- ### Python - requests 此次爬蟲所使用的程式語言為Python,是因為Python提供了許多好用的爬蟲套件,requests就是其中之一。 ---- ### requests是蝦米?? requests是一個幫助你抓下網頁的HTML原始碼的套件,抓下原始碼後才能對網頁進行分析。 ---- ### 下載requests ``` // CMD pip install requests ``` ### 引用requests ```python= import requests ``` ---- ### requests抓取網頁HTML原始碼 抓取網站使用到 requests.get() 函數,參數為我們想要爬蟲的網址(URL) ```python= response = requests.get("https://www.ptt.cc/bbs/Gossiping/index.html") ``` ---- ### 你以為抓下來就可以直接用了嗎,並沒有! 抓下來的還只是最原始的HTML,需要透過BeautifulSoup解析。 ---- ### BeautifulSoup又是蝦米?? BeautifulSoup是一個解析HTML原始碼並且提供搜尋節點功能的套件。 ![](https://i.imgur.com/eNL70dh.png =30%x) ---- ### 下載BeautifulSoup ``` // CMD pip install beautifulsoup4 ``` ### 引用BeautifulSoup ```python= from bs4 import BeautifulSoup ``` ---- ### BeautifulSoup解析網頁HTML原始碼 ```python= response = requests.get("https://www.ptt.cc/bbs/Gossiping/index.html") soup = BeautifulSoup(response.text, "html.parser") print(soup.prettify()) ``` ---- ### 結果... ![](https://i.imgur.com/ZhUlHqz.png) <!-- last page of ch3 --> --- ## 4. 你騙我! 你不是說這樣就可以抓到HTML了嗎? --- #### cookie介紹 ---- ### 我們來找找看原因 第一次進入PPT八卦板時,會先看到這個畫面: ![](https://i.imgur.com/8HOiGFG.png) 點 "我同意" 之後才會看到文章列表。 但第二次再進去時,就不會再詢問一次是否滿18歲了,這是為什麼呢? ---- 我們觀察 **F12>>Application>>Cookies** ![](https://i.imgur.com/LiVKv1b.jpg) ---- 然後當我按下 "我同意" 時,cookie會多出一個 over18=1,這就是PTT存在瀏覽器中,記錄我是否點過滿18的餅乾。 ![](https://i.imgur.com/Dz53JA8.jpg) ---- 再來觀察 **Network>>index.html>>Headers>>cookie**,會發現PTT就是把cookie包裝在Headers中發送出去的。 ![](https://i.imgur.com/Fx7fEhw.jpg =90%x) ---- 也就是說,我們只要讓程式模擬使用者,發送一個一樣的cookie,就能順利抓到文章列表了! ```python= my_headers = {"cookie": "over18=1"} url = "https://www.ptt.cc/bbs/Gossiping/index.html" response = requests.get(url, headers=my_headers) soup = BeautifulSoup(response.text, "html.parser") print(soup.prettify()) ``` ---- ### 結果... ![](https://i.imgur.com/b3rZimq.png) ![](https://i.imgur.com/9elgmgr.png) ![](https://i.imgur.com/dtS8Mfr.png) ![](https://i.imgur.com/mHBXwxx.png) ---- 其實可以將cookie想成暫存在用戶端(client)這邊的便利貼,上面記錄了你之前的所做過的事情,之後在進相同的網頁時,就會連著cookie帶給伺服器,好讓伺服器知道你做過什麼事。 <!-- last page of ch4 --> --- ## 5. 看起來不錯,但好像少了些什麼? --- #### session介紹 ---- 繼續做下去你可能會發現,當每次向伺服器送出請求(Request)時,都必須補上cookie,伺服器才會正確的傳回網頁,這是為什麼呢? ---- 在網頁的世界裡,它是一個「無狀態」的協議。什麼意思呢?那就是每一個 request 都是一個「獨立的」request,彼此之間不會有任何關聯。所以 Server 那邊也不會保存任何狀態。每一個 request 都是一個新的 request。 ---- 你可以把伺服器想成是一個喪失記憶能力的人,每一次你去找他的時候,他都當作是第一次見到你,完全忘記你以前有去找他了。 就會發生... ---- ![](https://i.imgur.com/LUhdhfA.png =40%x)![](https://i.imgur.com/4FGfF0U.png =40%x) ---- ### 我懂了,但每次都要傳cookie我覺得好麻煩,有沒有更好的做法? ---- ### 有的,那就是session~ ---- ### session是什麼? session的英文意思是 *持續一段時間的狀態*,基本上和它的運作方式並沒有差太多,此機制確保了伺服器可以知道使用者的狀態。 ---- 想像伺服器留下一張便利貼,上面留者你的一切所作所為,並給你一個密碼,那當你下次拿著這個密碼來找伺服器時,伺服器就會對應到那張便條紙,就可以知道你之前做了哪些事了。 簡單來說,你可以把session當作是存在伺服器端(server)的cookie。 ---- ### session該怎麼用? requests有內建session()函數,會暫存使用者的資料。 ```python= rs = requests.session() ``` ---- ### 跟cookie有點不一樣 前面我們是讓程式將cookie夾帶在headers中傳送給伺服器,但缺點是每次request都必須補上cookie,相當麻煩。 所以我們希望==程式可以模擬的像是真人==,回想一下,我們剛剛進八卦版做了哪些事情? ---- 1. 先進入 "詢問你是否滿18歲" 的畫面 2. 然後你按了 "我同意" 3. 瀏覽器存下 "over18的cookie" 4. 進入文章列表 ---- ### 那麼,我們怎麼讓程式做一樣的事呢? ```python= payload = { 'from': '/bbs/Gossiping/index.html', 'yes': 'yes' } # 用session紀錄此次使用的cookie rs = requests.session() response = rs.post("https://www.ptt.cc/ask/over18", data=payload) ``` ---- ### post vs. get * get: 將資料全部寫在header上,就像你寫明信片一樣,傳遞上較不安全。 * post: 將資料寫在內部,就像你寫信然後裝進信封袋一樣,傳遞上比較安全且傳遞的資訊可以比較多。 ---- ### post 使用 data 參數傳遞資料 查看 **Network>>over18>>Headers>>Form Data** 我們看到了這兩個參數,不難猜測代表的意思。 * from: 代表我們進入的是八卦版。 * yes: 代表按了同意。 ![](https://i.imgur.com/WhaxWRR.png =100%x) ---- ### 看看是不是成功了 ```python= response = rs.get("https://www.ptt.cc/bbs/Gossiping/index.html") soup = BeautifulSoup(response.text, "html.parser") print(soup.prettify()) ``` 結果會和上一個一樣,不過你會發現如果想要再進入一次八卦版的話,就不需要再傳cookie了。 ---- ### 好session,不用嗎? ![](https://i.imgur.com/EnQ9D9k.png =60%x) ---- ### 爬蟲重要觀念 ### ==讓程式模擬真人的行為== 因為爬蟲會造成伺服器的負擔,所以大部分網站都不歡迎別人來爬他們的網站,因此多數網站都會設下許多障礙阻止爬蟲。 想當然,魔高一尺道高一丈,身為一個爬蟲工程師,就要想盡辦法==讓你的程式看起來像是真人==,以騙過伺服器的眼睛。 <!-- last page of ch5 --> --- ## 6. 抓到了沒錯,可是,我們要的東西在哪裡? --- #### BeautifulSoup分析HTML+搜尋節點 ---- ### 先別急,我們先來觀察一下八卦版 ---- 文章標題按右鍵>>檢查 ![](https://i.imgur.com/bXeeuK6.png) ---- 會出現文章標題在HTML上的位置 ![](https://i.imgur.com/9ezbUoD.png) ---- 多抓幾篇會發現,所有的標題都放在一個 ==class="title" 的 div 中== ![](https://i.imgur.com/5em1ZQ5.png) ![](https://i.imgur.com/n11aRUl.png) ---- ### BeautifulSoup搜尋節點 * find_all("標籤名稱", 屬性="值"): ```python= links = soup.find_all("div", class_="title") for link in links: print(link) ``` 找到所有 class 名稱為 "title" 的 "div" , 回傳一個列表。 ---- ### 結果... ![](https://i.imgur.com/YpT2ak2.png) <!-- last page of ch6 --> --- ## 7. 我們要什麼? 我們要連結! --- #### 抓出每篇文章的連結 ---- 因為我們想要文章的詳細資料,因此我們必須進到文章內才能抓到。 **那麼,要怎麼抓出文章聯結呢?** ---- ### 我們先看一下剛剛抓到的東西 ``` <div class="title"> <a href="/bbs/Gossiping/M.1615705592.A.DEE.html">[問卦] 高雄最美的景點是什麼?</a> </div> ``` 會發現我們要的連結是在 ==`<a>`中的"href"屬性==。 ```python= links = soup.find_all("div", class_="title") for link in links: print(link.a["href"]) ``` ---- ### 結果 ![](https://i.imgur.com/OzRqsWs.png =80%x) ---- 但這並不是完整的網址,所以我們要在前面加上: "https://www.ptt.cc/" ---- ### 結果 ![](https://i.imgur.com/RgHtTQ3.png =80%x) ---- 還記得requests的get函數嗎? 接下來就用此函數進到文章內頁。 ```python= page_url = "https://www.ptt.cc/"+link.a["href"] # 進入文章頁面 response = rs.get(page_url) result = BeautifulSoup(response.text, "html.parser") print(result.prettify()) ``` ---- ### 結果 ![](https://i.imgur.com/cHBl3rd.png =45%x) <!-- last page of ch7 --> --- ## 8. 一切都準備好啦! --- #### 抓出文章的作者、標題、發文時間 ---- 檢查文章作者、標題、發文時間的位置 **右鍵>>檢查** ![](https://i.imgur.com/6Hw1wii.png) ---- 發現都會在 ==class="main-content" 的 div 中== ![](https://i.imgur.com/l5oB6is.png) ---- 再往下找到 ==class="article-meta-value" 的 span 中== ```python= # 找出作者、標題、時間、留言 main_content = result.find("div", id="main-content") article_info = main_content.find_all("span", class_="article-meta-value") ``` ---- 因為會用list的方式裝下來,就用索引值取我們要的資料吧~ ```python= if len(article_info) != 0: author = article_info[0].string # 作者 title = article_info[2].string # 標題 time = article_info[3].string # 時間 else: author = "無" # 作者 title = "無" # 標題 time = "無" # 時間 ``` 很小機率會出現沒有 "article-metaline" 等資訊還是要特殊處理 QAQ --- ## 9. 都是一樣抓東西,應該很簡單吧~(Flag --- #### 抓出文章內容 ---- ### 到文章內容>>右鍵>>檢查 ---- 結果內容不存在任何類別內。只是單純的丟到 "main-content" 而已 ![](https://i.imgur.com/h6LvRUJ.png) **那麼到底要怎麼把內容抓下來OAO?** ---- ### 也只能再仔細觀察文章內容在HTML內的形式 ---- 檢查過每篇不同文章,就會發現文章都是以 "- -" 來做結尾的 ![](https://i.imgur.com/FaDdQcB.png) ---- 把先前抓的 "main_content" 文字的部分(text),再用 `split()` 函數丟掉後面不需要的。 又因為文章內可能也含有 "- -" 符號而不小心被切割,再用 `join()` 函數恢復原樣。 ```python= # 將整段文字內容抓出來 all_text = main_content.text # 以--切割,抓最後一個--前的所有內容 pre_texts = all_text.split("--")[:-1] # 將前面的所有內容合併成一個 one_text = "--".join(pre_texts) ``` **這樣子文章後面的部分搞定啦** ---- 試著先把目前抓到的print出來檢查 ![](https://i.imgur.com/Oljgk4L.png) 發現文章是從第一個換行後開始,所以就用 "\n" 來做分割~ ---- 跟上面一樣的方法,只是改成 "\n"。 ```python= # 以\n切割,第一行標題不要 texts = one_text.split("\n")[1:] # 將每一行合併 content = "\n".join(texts) ``` **文章內容全部搞定w** --- ## 10. 蛤?管你是誰發的,我全都要! --- #### 抓出留言並分類 ---- ### 到流言處>>右鍵>>檢查 ---- 所有留言都是放在==class="push" 的 div 內== 然後再細分出 "push-tag" "push-userid" "push-content" "push-ipdatetime" ![](https://i.imgur.com/BHUvTxe.png) ---- 跟前面一樣使用BeautifulSoup。 ```python= # 抓出所有留言 comments = main_content.find_all("div", class_="push") for comment in comments: push_tag = comment.find( "span", class_="push-tag").string # 分類標籤 push_userid = comment.find( "span", class_="push-userid").string # 使用者ID push_content = comment.find( "span", class_="push-content").string # 留言內容 push_time = comment.find( "span", class_="push-ipdatetime").string # 留言時間 ``` ---- 為了分類,我建立三個list,分別存放"推"、"→"、"噓"三種標籤。 ```python= push_dic = [] arrow_dic = [] shu_dic = [] ``` ---- 以字典型式將所有資料塞好塞滿,然後再依照標籤分類囉~ ```python= dict1 = {"push_userid": push_userid, "push_content": push_content, "push_time": push_time} if push_tag == "推 ": push_dic.append(dict1) if push_tag == "→ ": arrow_dic.append(dict1) if push_tag == "噓 ": shu_dic.append(dict1) ``` --- ## 11. 抓一頁不夠,那就抓兩頁阿! --- #### 自動換頁 ---- #### 現在只能取得一頁的文章,但如果想要取得其他頁的文章該怎麼做? ---- #### 我們想要看上一頁時,會做什麼事? ---- 對上方導覽列的 "上頁" 按鈕,使用**右鍵>>檢查**。 我們要的連結在==string="‹ 上頁" 的 `<a>` 中== ![](https://i.imgur.com/5cyNOug.png) ---- 把新的連結給url,再來就用for迴圈做到想要的頁數吧~ ```python= # 找到上頁的網址,並更新url url = "https://www.ptt.cc/"+ soup.find("a", string="‹ 上頁")["href"] ``` --- ## 12. JSON是什麼挖糕? --- #### JSON格式介紹 ---- 以易於讓人閱讀的文字為基礎,用來傳輸由屬性值或者序列性的值組成的資料交換語言 -- 維基百科 ![](https://i.imgur.com/o4ALd1u.png =300x) ---- python 與 json 的差別 ![](https://i.imgur.com/TBjpKm9.png) ---- #### 簡單來說,json就是單純由list、dict型態所組成的複合資料型態。 ---- #### 所以,我們要做的前置作業就是把資料整理好,以利將其轉成json檔。 ---- 首先,宣告一個list,名稱為data。 ```python= data = [] # 全部文章的資料 ``` 再來,宣告一個dict,名稱為article_data。 ```python= article_data = {} # 單篇文章的資料 ``` 以及另一個dict,名稱為comment_dic。 ```python= comment_dic = {} # 所有留言 ``` dict的格式:`{"key": "value"}` ---- 所有資料包起來 ```python= article_data["author"] = author article_data["title"] = title article_data["time"] = time article_data["content"] = content comment_dic["推"] = push_dic comment_dic["→"] = arrow_dic comment_dic["噓"] = shu_dic article_data["comment"] = comment_dic data.append(article_data) ``` ---- #### 最後轉成json格式後,如果只是單純顯示在terminal上會很難辨識,也很難讓其他程式使用。 ---- #### 那就乾脆寫檔匯出吧! Python內建有json套件,利用 *dump()* 將其轉成json然後匯出囉! ```python= import json ``` ```python= # 輸出JSON檔案 with open('data.json', 'w', encoding='utf-8') as f: json.dump(data, f) ``` ---- 可以到網站[json editor](https://jsoneditoronline.org/),可以很方便的確認最後匯出的json檔喔~ ![](https://i.imgur.com/yTNhBCq.png) ---- #### 有了這些資料後,就可以用於其他的應用了~ --- ## 總結 --- 這堂課先從網頁的架構HTML開始,接著以PPT八卦版為例,代入cookie和session概念,以及使用Python的requests和BeautifulSoup套件篩選出我們要的資料,到最後匯出成JSON格式。 --- ## Q & A ---- Q1: 所以我們這麼辛苦抓下了這些資料要做什麼? A1: 在機器學習上,資料量決定了訓練出來的精準度,因此這些資料可是非常重要的喔! ---- Q2: 我不是上面講的那些人員,我也可以爬蟲嗎? A2: 當然可以! 只要你是要從網路上取得大量資料,而且想要電腦幫你完成這件事的人,就可以利用爬蟲幫你省下大量時間! ---- Q3: 我想爬爬看別的網站,但我不知道從何開始下手? A3: 一開始可以先從PTT的其他版開始,因為PTT應該算是最好爬的網站了,等到比較熟悉之後,就可以開始爬其他網站了,爬蟲的重點就是要**多觀察**,多利用**右鍵>>檢查**來了解原始碼的樣子,或到**F12>>網路**檢查傳了什麼request給伺服器,都能幫助你更了解這個網站的運作方式,並找出破綻來取得資料。 ---- Q4: 我用這堂課教的方法在爬某個網站時,發現無論如何都抓不到資料,怎麼會這樣? A4: BeautifulSoup和requests並不是萬用的,爬蟲還有很多的技巧可以用,不同的技巧對應到不同的情況,但這部分就要由你們自己去探索囉! --- [完整程式碼GitHub網址](https://github.com/AndyChiangSH/NCHU_topic_homework/tree/master/hw01_PTT%20crawler) --- ## Homework --- 爬[PTT政黑板](https://www.ptt.cc/bbs/HatePolitics/index.html),跟我做一樣的事情。 完成後將程式碼寄到我的信箱 **chiang1051009@gmail.com**。 信件標題格式為 **學號-系級-姓名**。 程式碼需要註解說明每一段的功用。 --- ## END ![](https://i.imgur.com/rTUnT06.png =50%x)

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully