# 網路爬蟲
Vincent55 楊竣鴻
Note:
2023-07-11 09:20 - 11:20
2023-07-11 14:50 - 16:50
上課前先解釋如何使用這份簡報,可以使用編輯模式看 Note 跟範例
---
## 這堂課你會學/操作到
- 網頁基本原理
- 爬蟲常用套件
- Requests
- BeautifulSoup
- Selenium
- API
---
# 網頁基本原理與複習
- HTTP request/response
- HTTP methods
- HTML、JavaScript、CSS
Note:
在進到爬蟲之前,先介紹什麼是 HTTP,包含了 HTTP methods 跟 Requests 與 Response,再來會介紹網頁上的三個主要的元素 HTML CSS JavaScript
----
## HTTP requests
![](https://hackmd.io/_uploads/H1YDd5srn.png)
ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview
Note:
可以看到這張圖的左邊代表了我們目前看到的介面就是瀏覽器,也就是客戶端,其實我們的一些資源是向伺服器去做請求的,可以看到像是 Image 是向 Web Sever 發出 http get 的請求, Video 則是向 Video Server 發出 http get 的請求
----
## HTTP methods
http://dev.vincent55.tw/
| methods | 功能 | 參數 |
| -------- | -------- | -------- |
| GET | 取得資料 | `?key1=value1&key2=value2` |
| POST | 上傳資料 | key1=value1&key2=value2 |
| DELETE | 刪除資料 | |
| PATCH | 更新資料 | |
Note:
剛有提到 HTTP GET,GET 是一種 HTTP Methods,主要是在取得資料的時候使用的 Method,同時在請求時也可以放參數
可以發現在使用 GET 請求放置參數的時候是直接放在網址後方,這樣就不太安全,例如在登入的時候填寫帳號密碼,若有中間人或有人站在你後面,那很容易被看到。
POST 請求常會用在表單發送的時候,他會將參數放在 Requests body 內。
----
## HTTP response code
https://http.cat/
Note:
我們發出了一個 HTTP requests 後,伺服器就會回一個 response,那這時候我們可以透過 response status code 來看回應的狀態。
1XX – 連接正在進行中。
2XX – 請求成功完成,伺服器給了瀏覽器預期的響應。
3XX – 這個請求被收到了,但是需要重新定向。
4XX – 請求已經發出,但頁面無效 - 這是網站一方的錯誤,通常在頁面不存在的情況下出現。
5XX – 客戶端的請求是有效的,但伺服器未能完成請求。
----
## 聽說 F12 可以駭入小恐龍 (1/3)
- 瀏覽器開發人員工具
![](https://hackmd.io/_uploads/H1a0gniHh.png)
Note:
了解 HTTP 基本使用方式後,我們可以使用大多數瀏覽器內建的開發者工具來做測試
----
## 聽說 F12 可以駭入小恐龍 (2/3)
![](https://hackmd.io/_uploads/H1gcpqGLh.png)
Note:
可以開 https://csie.ncku.camp/ 來演示
元素面板 Elements : 可以看到當前網頁的 DOM 物件、HTML、CSS 並能修改。
控制面板 Console : 目前網頁訊息,可以與 JavaScript 進行命令互動。
來源面板 Source : 可設定目前 JavaScript 的斷點,並測試運行。若網頁是架在本機,能直接存檔。
網路面板 Network : 檢測目前網頁由外向內、由內向外的網路流量,可以看到詳細這些流量的內容(requests header、post data ...)
性能面板 Performance : 紀錄網頁生命週期中發生的事件,用來調整網頁的性能。
內存面板 Memory : 用於檢測當前內存的使用狀態。
應用面板 Storage : 檢測載入資源。 e.g. Local Storage 、 cookies 、 Cache
----
## 聽說 F12 可以駭入小恐龍 (3/3)
`chrome://dino/`
- 在 Console 打入
- `Runner.instance_.setSpeed(1000000)`
Note:
剛才有提到 Console 可以與網頁的 JavaScript 做互動,因此我們能透過與小恐龍的的互動來調整速度
從這個例子我們能看到跑在網頁的 JavaScript 是可以修改的,因此網頁設計者常會將 JavaScript [混淆](https://obfuscator.io/) 讓人難以查看真正行為
----
## 網頁三要素
- HTML - 骨骼
- CSS - 皮膚
- JavaScript - 大腦
Note:
將網頁比做人體,HTML CSS JavaScript 分別對應了骨骼 皮膚 大腦
HTML 提供了我們網頁的基本架構,比如我們需要一段文字跟一個按鈕
有了基本架構後,CSS 可以美化這個頁面,讓文字的自行修改,與按鈕的大小
以上都只是網頁外表的部分,我們需要 JavaScript 來提供邏輯,建立出可以與使用者互動的介面。
----
## HTML(1/2)
- 超文本標記語言
- Document Object Model (DOM)
![](https://hackmd.io/_uploads/B1s_DdtK3.png)
Note:
HTML 是一個標記語言,可以看到途中的下方, html head title 各是一個 tag,由一個角括號與文字表示
瀏覽器透過 http requests 取得 HTML 後,會將其轉換為 DOM,並渲染到畫面上,DOM 是一個樹狀的架構,每個標籤都是一個節點,可以用來表示我們的 HTML
可以看到我們最上層的標籤是 html,接下來有 head 跟 body,head 代表了我們網頁的基本資訊, body 代表了網頁的內容。
可以看到有些標籤裡面有一些屬性 class id 等,能讓 CSS 跟 JavaScript 鎖定到元素
----
## HTML(2/2)
- Document Object Model (DOM)
- 節點之間的關係
![](https://hackmd.io/_uploads/SkwDnjjBh.png)
Note:
我們有了 DOM 後,猶豫他是一個樹狀結構,因此我們能簡單的在節點與節點之間移動
----
## CSS
- CSS 通常會寫在 HTML 的 head 或者獨立出來一個 CSS file
- CSS Selector
- CSS 用來鎖定元素的 [規範](https://developer.mozilla.org/zh-TW/docs/Web/CSS/CSS_Selectors)
```HTML=
<head>
<link rel="stylesheet" type="text/css" href="mycss.css">
<style>
body{
background:#fff;
color:#777;
}
h1{
font-weight:bold;
font-style:italic;
font-family:sans-serif;
color:green;
}
a {
color: #0077cc;
text-decoration: none;
}
.container {
border: 2px solid #ccc;
padding: 20px;
border-radius: 10px;
}
</style>
</head>
```
Note:
CSS 可以用來美化我們的介面,CSS 通常會寫在 HTML 的 head 用 style 標籤包起來,或者獨立一個 css file 再透過引入的方式使用。
在爬蟲這堂課裡面,CSS 可以只需要了解 CSS 選擇器,在 CSS 裡面是透過 CSS 選擇器來鎖定元素的去替換屬性,那這個特性我們可以來利用在爬蟲的時候定位元素。
----
## JavaScript
- 語言特性
- 單執行緒
- 非同步
- https://developer.mozilla.org/zh-TW/docs/Learn/JavaScript/Asynchronous/Introducing
- http://latentflip.com/loupe/
- 動態弱型別語言
- https://openhome.cc/zh-tw/javascript/basics/wat/
Note:
單執行緒: 一次只做一件事,一次只占用一個執行緒
非同步: 在執行非同步函式的時候不會等待回傳值占用執行緒,透過事件迴圈 (Event loop)實現
動態語言: 變數的型態不在定義階段時決定
弱型別: 變數在與不同型態的變數互動時,可以被隱式轉換為另一個類型
----
## 挑戰 1 - 開發人員工具練習
https://jupiter.challenges.picoctf.org/problem/9670/
- 找到完整的 flag
- 共有三個部分
Hint: 使用開發人員工具,檢查 HTML CSS JavaScript
---
# 爬蟲常用套件
----
## 爬蟲是什麼
- 一種依照特定規則抓取網路資訊的程式
- 股票爬蟲
- PTT 爬蟲
- 搜尋引擎
Note:
剛才我們操作的都是透過瀏覽器向伺服器發送 HTTP 請求,但其實不只瀏覽器可以做到,可以透過程式來向伺服器發送 HTTP 請求
網路爬蟲就只是一種透過特定的規則去抓取網路資訊一個程式
----
## 爬蟲是怎麼運作的
- 取得網路資訊
- 網頁原始碼、API
- 解析資訊
- 解析工具們
- 開發人員工具、眼睛...
- 資料清洗工具們
- BeautifulSoup、regex...
- 後續使用
- 存起來
- 傳給自己
- Telegram、Line...
Note:
網路爬蟲是怎麼從零到有產生的
----
## Requests (1/4)
> Requests is a simple, yet elegant, HTTP library.
- 用 Python 向網站發 HTTP 請求
- <img src="https://warehouse-camo.ingress.cmh1.psfhosted.org/98d69ff5a75b6a9a8cbb54b7ce9c126f9d857f79/68747470733a2f2f706570792e746563682f62616467652f72657175657374732f6d6f6e7468" alt="Downloads">
Note:
request 是一個 Python 的函式庫,讓我們可以透過簡單的語法向伺服器發出 HTTP 請求
----
## Requests (2/4)
- 安裝
- `pip install requests`
```python=
import requests
#先將欲發出 GET 請求的網址先存在 url
url = 'https://example.com/'
#對 url 發出 GET 請求,並將 Response 物件存在 res
res = requests.get(url)
print(type(res), res)
#Output: <class 'requests.models.Response'> <Response [200]>
```
Note:
這邊是一個範例
----
## Requests (3/4)
- Response 物件的使用方式
- res.status_code : 該 HTTP 狀態碼
- res.text : 回應物件的字串(str)型態
- res.json() : 將回應物件透過 JSON decoder 回傳 JSON 格式。
- ...
- [官方文件](https://requests.readthedocs.io/en/latest/user/quickstart/#response-content)
Note:
取得 Response 物件後,我們可以有許多使用的方法,可以使用 status_code 取得 HTTP response code,或者使用 text 取得字串型態的回傳,我們接下來會很常使用這個,以及 .json() 可以幫助我們解析回傳值為 json 格式
----
## Requests (4/4)
```python=
import requests
#先將欲發出 GET 請求的網址先存在 url
url = 'https://example.com/'
#對 url 發出 GET 請求,並將 Response 物件存在 res
res = requests.get(url)
print(res.text)
'''
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
'''
```
----
## 挑戰 2 - 取得官網原始碼
`https://csie.ncku.camp/`
----
## API
政府資料開放平台 https://data.gov.tw/
Note:
把網站比做一個餐廳,前端就像一個外場,就是現在各位看的的頁面,而後端就是一個餐廳的後台,用來處理外場的需求,API 就是一個菜單,供客人知道該怎麼取得對應資料或服務,之間傳遞資料的格式現今最常見的就是 JSON
政府資料開放平台讓我們可以透過 API 的方式取得政府資訊。
----
## JSON
- 一種輕量級資料交換格式
- 物件、陣列、數值、字串、布林值、空值
```
{
"firstName": "John",
"lastName": "Smith",
"sex": "male",
"age": 25,
"ismarry": false,
"child": null,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"phoneNumber": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "fax",
"number": "646 555-4567"
}
]
}
```
Note:
JSON 是一種輕量級資料交換格式,資料型態只有這邊列出的六種,其中物件可以把它想成是 Python 的 dict,也是一種 key-value 的架構,陣列則是能儲存多個值。
JSON 被廣泛利用在前端與後端的資料交換,與設定檔格式,像是 minecraft 就是使用 JSON 作為設定檔格式,甚至有些人會選擇將他當作資料庫來使用,因此很多語言都有內建 JSON 的函式庫
----
## JSON
- Python 標準庫裡面有 json 工具
- `import json`
- https://docs.python.org/zh-tw/3/library/json.html
- Requests 裡面也有內建
- `response.json()`
Note:
我們在 Python 裡面可以透過 import 的方式來引入 json,以及剛才提到的 Requests 的 Response 物件也有內建 JSON 解析器
----
## JSON 檔案操作
- 檔案名稱
- `xxx.json`
- JSON 儲存到 `.json` 檔案
```
with open('result.json', 'w', encoding='utf-8') as f:
json.dump(res, f, indent=2, sort_keys=True, ensure_ascii=False)
```
- 從 `.json` 檔案取得 JSON
```
with open('result.json', 'r') as result_fd:
result_file = json.load(result_fd)
print(result_file)
```
Note:
我們可以透過存檔讀檔的方式將 json 作為一種資料庫來儲存資料。
----
## JSON
```python=
import requests
import json
#先將欲發出 GET 請求的網址先存在 url
url = 'http://dev.vincent55.tw/json'
#對 url 發出 GET 請求,並將 Response 物件透過 json 解析後存在 res
res = requests.get(url).json()
print(type(res), res)
print(res['slideshow']['slides'][1]['title'])
# 將回傳值存於 result.json
with open('result.json', 'w', encoding='utf-8') as f:
json.dump(res, f, indent=2, sort_keys=True, ensure_ascii=False)
'''
<class 'dict'> {'slideshow': {'author': 'Yours Truly', 'date': 'date of publication', 'slides': [{'title': 'Wake up to WonderWidgets!', 'type': 'all'}, {'items': ['Why <em>WonderWidgets</em> are great', 'Who <em>buys</em> WonderWidgets'], 'title': 'Overview', 'type': 'all'}], 'title': 'Sample Slide Show'}}
Overview
'''
```
----
## 挑戰 3 - 取得貓貓圖片
https://api.thecatapi.com/v1/images/search
- 可以輸入一個數字,取得該數量的貓貓圖片,並儲存到 `result.json` 裡面
- 進階挑戰
- 如果有重複執行該程式,`result.json` 不會被覆蓋
- Hint: 可以善用讀檔與寫檔
----
## BeautifulSoup (1/4)
- 從 HTML 或 XML 檔案中解析資料
- 也可拿來修復未閉合標籤等錯誤的文件
Note:
若沒有 API 可供使用, 我們就需要自行去解析原始碼內容,BeautifulSoup 是一套可以解析 HTML 的工具,提供了很多好用的選取器取得想要的資料。
我們可以透過 requests 的 Response 物件的 text 取得字串型態的回傳值,再來我們可以透過 BeautifulSoup 去解析內容。
----
## BeautifulSoup (2/4)
- 安裝
- `pip install beautifulsoup4`
```python=
from bs4 import BeautifulSoup
html_text = """
<html><head></head><body><h1>Hello, World!</h1></body></html>
"""
soup = BeautifulSoup(html_text, "html.parser")
print(soup.prettify())
```
```text
<html>
<head>
</head>
<body>
<h1>
Hello, World!
</h1>
</body>
</html>
```
Note:
html_text 是一個 HTML 字串的範例,透過 BeautifulSoup 解析,之後使用 prettify 查看解析的狀態。
----
## Beautifulsoup (3/4)
- soup.find() : 根據條件回傳"第一個"符合的元素
- `soup.find('p', id='myid', class_='myclass')`
- soup.find_all() : 根據條件回傳"所有"符合的元素,由串列表示。
- soup.select_one() : 透過 CSS Selector "第一個"符合的元素
- soup.select() : 透過 CSS Selector "所有"符合的元素,由串列表示。
Note:
BeautifulSoup 提供了一些選取器
----
## Beautifulsoup (4/4)
```python=
from bs4 import BeautifulSoup
import requests
# 將 resp.text 也就是 HTML 資料定義到 BeautifulSoup 物件內,並用 html.parser 解析 HTML 內容
soup = BeautifulSoup(requests.get(url).text, "html.parser")
# 輸出網頁的 title
print(soup.title.getText())
#輸出第一個尋找到的 <li> 元素的文字
print(soup.li.getText())
#輸出第一個尋找到的 <li> 元素的文字(相同效果)
print(soup.find('li').getText())
#尋找全部 <li> 元素的文字
lis = soup.find_all('li')
for li in lis:
print(li.getText())
```
----
## 案例 - ptt 棒球版爬蟲 (1/3)
https://www.ptt.cc/bbs/Baseball/index.html
- class="r-ent"
![](https://hackmd.io/_uploads/Byjn9KnH2.png)
Note:
觀察一下頁面可以發現各個文章有個共通點就是都有 r-ent 這個 class ,因此我們能透過 find_all 的方式取得所有文章
----
## 案例 - ptt 棒球版爬蟲 (2/3)
```python=
from bs4 import BeautifulSoup
import requests
url = "https://www.ptt.cc/bbs/Baseball/index.html"
r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")
for article in soup.find_all(class_="r-ent"):
print(article)
```
Note:
取得所有文章後,檢查我們需要元素的 class
----
## 案例 - ptt 棒球版爬蟲 (3/3)
```python=
from bs4 import BeautifulSoup
import requests
import json
url = "https://www.ptt.cc/bbs/Baseball/index.html"
r = requests.get(url)
soup = BeautifulSoup(r.text, "html.parser")
results = []
for article in soup.find_all(class_="r-ent"):
results.append({
"title":article.find(class_="title").text.strip(),
"author": article.find(class_="author").text.strip(),
"link": article.find(class_="title").a['href']
})
# 將回傳值存於 result.json
with open('result.json', 'w', encoding='utf-8') as f:
json.dump(results, f, indent=2, sort_keys=True, ensure_ascii=False)
```
----
## 挑戰 4 - ptt 棒球版爬蟲(自動換頁)
https://www.ptt.cc/bbs/Baseball/index.html
Hint: 可將目前的爬蟲寫成一個 function,並且每次都用爬蟲去取得上一頁的連結
Note:
如果學員提早完成了,可以請他將結果以 JSON 儲存
---
# Selenium
- 動態載入網頁資料
- 模擬使用者在瀏覽器的行為
- 點擊按鈕、輸入帳號密碼、捲動捲軸
Note:
我們剛才學的都是使用 HTTP request 取得我們要的資源,但有些頁面是透過 JavaScript 去動態產生資料的,這時候我們就需要另外一種爬蟲的方式
例如 Selenium 是可以模擬瀏覽器的工具,就像我們在瀏覽一個頁面一樣,能動態的渲染頁面
----
## Selenium
- 安裝
- `pip install selenium webdriver-manager`
Note:
為了讓Selenium可以自動化控制瀏覽器,我們必須先安裝瀏覽器的驅動程式
----
## Selenium
```python=
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
time.sleep(10)
driver.close()
```
Note:
ChromeDriverManager 可以自動下載符合環境的瀏覽器驅動程式,讓 Selenium 能夠使用該驅動程式來啟動瀏覽器
----
## Selenium
```python=
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
driver.get("http://www.python.org") #前往該網頁
elem = driver.find_element(By.NAME, "q") #找到特定元素
elem.clear() #將該欄位清空
elem.send_keys("nckucsie") #模擬使用者打入字串
elem.send_keys(Keys.RETURN) #模擬試用者 Enter
time.sleep(5) #sleep 5 秒查看結果
driver.close() #將 driver 關閉
```
Note:
demo 這段程式,確保學員能夠跑起來
----
## 鎖定元素
- https://selenium-python.readthedocs.io/locating-elements.html#locating-elements
Note:
Selenium 提供了很多方法來選取到想要的元素
回到上一頁說明鎖定元素的過程
----
## 案例 - 取得頁面所有文章
https://forum.gamer.com.tw/
![](https://hackmd.io/_uploads/rJHO6BvK2.png)
Note:
```python=
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import json
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
#前往該網頁
driver.get("https://forum.gamer.com.tw/")
#找到特定元素
forum_lists = driver.find_elements(By.CLASS_NAME , "forum_list")
result = []
#遍歷每個文章
for forum in forum_lists:
#取得各文章的內容
result.append({
"title": forum.find_element(By.CLASS_NAME, "forum_list_title").text,
"url": forum.find_element(By.TAG_NAME, "a").get_attribute("href")
})
#儲存到 json file
with open('result.json', 'w', encoding='utf-8') as f:
json.dump(res, f, indent=2, sort_keys=True, ensure_ascii=False)
#將 driver 關閉
driver.close()
```
Note:
除了 find_element,也帶到 get_attribute 取得連結 href
----
## 鎖定到元素後可以幹嘛
- https://selenium-python.readthedocs.io/navigating.html
----
## 案例 - 捲動頁面
- 在 driver 執行 JavaScript
`driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")`
https://forum.gamer.com.tw/
Note:
```python=
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
#前往該網頁
driver.get("https://forum.gamer.com.tw/")
#捲動頁面到最下端
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
#sleep 五秒,觀察變化
time.sleep(5)
#將 driver 關閉
driver.close()
```
----
## 挑戰 5 - 巴哈姆特哈拉版爬蟲(自動捲動)
https://forum.gamer.com.tw/
Hint: 結合我們剛的兩個案例,先自動捲動後再取得文章
- 進階挑戰
- 在每次取得文章後,都進行捲動一次,並限制共會捲動幾次,且保證不會有文章重複
---
## 補充
----
### 更多爬蟲技巧
- 異步爬蟲
- 分析經驗
----
### 反爬蟲
- headers
- cookies
- proxy
----
### 專案上的建議
- 在開始動手前,先分析網站,搞不好能發現隱藏 API
- 不到最後關頭不使用模擬瀏覽器
---
## 謝謝各位
https://vincent55.tw/contacts/
----
### 如果一個 Package 沒有 \_\_init__.py
- Namespace package
- https://python3-cookbook-personal.readthedocs.io/zh_CN/latest/c10/p05_separate_directories_import_by_namespace.html
----
## more pip
- Wheel ( .whl )
- ![](https://hackmd.io/_uploads/r1NEtZqHh.png)
- 安裝包
- 本質上是一個 zip 檔
- 一種預編譯發行版的格式
- ready-to-install format
- `pip install <wheel file>.whl`
Note:
更小、安裝更快
解釋為何需要 compile
分享案例,在一家診所,需要自動讀取健保卡資料填入 X 光機控制軟體,作業系統是 windows XP,Python3 最高支援版本為 python3.4.4,沒有辦法連到外網,無法使用 pip 來下載 pypi 的 package,因此只好用 USD 將 wheel file 放到機器上用 pip install 下載
----
## pipenv
- pip + virtualenv
- Pipfile
- Pipfile.lock
----
## JavaScript 補充
- JavaScript 能拿來寫後端?
- Node.js ? JavaScript ?
- 為什麼要把 JavaScript 移植到後端?
> Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
V8 engine: https://chromium.googlesource.com/v8/v8
Note:
以 V8 為核心,加上一系列 C/C++ 的套件,成功的讓 Server 端也可以執行 JavaScript
JavaScript 自帶非同步,且語言特性適合用來接收高併發的需求
----
{"description":"Vincent 楊竣鴻 / 想要有效地利用 Python 套件 / Package / poetry / crawling / crawler / Requests / BeautifulSoup4 / BeautifulSoup / 2023-05-27 13:00","slideOptions":"{\"backgroundTransition\":\"none\",\"parallaxBackgroundSize\":\"1920px 1080px\",\"parallaxBackgroundHorizontal\":0,\"parallaxBackgroundVertical\":0}","title":"Python 網路爬蟲選修課程 - 成大資工資訊營","contributors":"[{\"id\":\"1e882b7f-b741-4bc1-9480-d5e91f0d2819\",\"add\":20115,\"del\":2310}]"}