# 網路爬蟲
網路爬蟲需要使用以下兩種函式庫:
1.requests:用於抓取網頁資料
2.BeautifulSoup:Python 外部函式庫,可以分析網頁的 HTML 與 XML 文件
## 使用網路爬蟲前:
進行網頁抓取或自動登入前,先檢查該網頁的 robots.txt 檔案和使用者協議
由此確認哪些資料可以被爬取。
**robots.txt 是一個由網站管理員用來指導網路爬蟲如何爬取和索引網站內容的文件。**
通過以下方法訪問網站之robots.txt
> https://your_url.com/robots.txt
## 使用爬蟲登入ncku moodle
引入request,beautifulsoup函式庫,並放入目標網址(moodle網址)
import requests
from bs4 import BeautifulSoup
BASE_URL = "https://moodle.ncku.edu.tw"
LOGIN_URL = BASE_URL + "/login/index.php" #在網路爬蟲中模擬登入操作
TARGET_URL = ""
有些時候,網站可能會檢查請求的 User-Agent 或其他頭部信息來區分普通的瀏覽器請求和自動化請求。用header可以嘗試模仿常見的瀏覽器 User-Agent。
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
# ... 可能還有其他 headers ...(在此以moodle的headers為例)
}
CSRF (跨站請求偽造) tokens 通常用於保護網站不受此類攻擊。當您嘗試從一個表單提交資料時,多數的網站會要求提供這樣的 token,以確認該請求是合法的。
可以用以下的方式取得tokens
with requests.Session() as s: #在with區塊內,創建一個http對話對象,像是對該對象s做了哪些事的概念。
獲取登入頁面和 CSRF token
response = s.get(LOGIN_URL, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
token_input = soup.find('input', {'name': 'logintoken'})
if not token_input:
raise ValueError("logintoken not found!")
logintoken = token_input['value']
然後進行登入,在login_data字典中放入帳號密碼,token
並使用s.post(網址,login_data,header)把網址,登入資料,header提交給網站
login_data = {
'username': 'E34111188',
'password': '********',
'logintoken': logintoken
}
response = s.post(LOGIN_URL, data=login_data, headers=headers)
if "登出" in response.text: #檢驗是否成功登入了
print("Successfully logged in!")
else:
print("Login failed!")
## 若要模擬像平常使用moodle,會保留住上次登入的資料
引進pickle套件。
pickle 是 Python 的一個內建模組,用於序列化(即將物件轉換為二進位)和反序列化(將二進位轉換回物件)Python 物件。在不丟失資料結構的情況下將物件保存到文件,以便以後再次使用。
import pickle #cookies 的保存
**with open('moodle_cookies.pkl', 'rb') as f:**
用於打開一個二進制文件,該文件名為 'moodle_cookies.pkl',並將其內容讀取到變數 f 中。
並讀取其內容存進cookies變數
with open('moodle_cookies.pkl', 'rb') as f:
cookies = pickle.load(f)
with requests.Session() as s:
#獲取登入頁面和 CSRF token
response = s.get(LOGIN_URL, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
token_input = soup.find('input', {'name': 'logintoken'})
if not token_input:
raise ValueError("logintoken not found!")
logintoken = token_input['value']
s.cookies = cookies #讀取舊的cookies,注意不能放在token_input前面,因為logintoken每次都會刷新?
#response = s.get(TARGET_URL, headers=headers)
if "登出" in response.text: #檢驗是否成功登入了
print("Successfully logged in!")
else:
print("Login failed!")
#with open('moodle_cookies.pkl', 'wb') as f: #保存cookies 到下一次登入
#pickle.dump(s.cookies, f)
完整程式碼為:
```
import requests
from bs4 import BeautifulSoup
import pickle #cookies 的保存
BASE_URL = "https://moodle.ncku.edu.tw"
LOGIN_URL = BASE_URL + "/login/index.php"
TARGET_URL = "https://moodle.ncku.edu.tw/mod/forum/view.php?id=713418"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
# ... 可能還有其他 headers ...
}
with open('moodle_cookies.pkl', 'rb') as f:
cookies = pickle.load(f)
with requests.Session() as s:
#獲取登入頁面和 CSRF token
response = s.get(LOGIN_URL, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
token_input = soup.find('input', {'name': 'logintoken'})
if not token_input:
raise ValueError("logintoken not found!")
logintoken = token_input['value']
s.cookies = cookies #讀取舊的cookies,注意不能放在token_input前面,因為logintoken每次都會刷新?
#response = s.get(TARGET_URL, headers=headers)
# 然後進行登入
login_data = {
#'username': 'E34111188',
#'password': '8861107Ex5',
'logintoken': logintoken
}
response = s.post(LOGIN_URL, data=login_data, headers=headers)
if "登出" in response.text: #檢驗是否成功登入了
print("Successfully logged in!")
else:
print("Login failed!")
#with open('moodle_cookies.pkl', 'wb') as f: #保存cookies 到下一次登入
#pickle.dump(s.cookies, f)
```