From 96d7a0c9ca446439f5e47a205914b5fe8081913e Mon Sep 17 00:00:00 2001 From: Edit-Mr Date: Mon, 6 Nov 2023 10:53:42 +0800 Subject: [PATCH] finished --- ...32\345\274\265\345\234\226\347\211\207.py" | 15 + index.html | 952 ++++++++++++++++++ spider.md => "\347\260\241\345\240\261.md" | 202 ++-- 3 files changed, 1084 insertions(+), 85 deletions(-) create mode 100644 "code/\344\270\213\350\274\211\345\244\232\345\274\265\345\234\226\347\211\207.py" create mode 100644 index.html rename spider.md => "\347\260\241\345\240\261.md" (88%) diff --git "a/code/\344\270\213\350\274\211\345\244\232\345\274\265\345\234\226\347\211\207.py" "b/code/\344\270\213\350\274\211\345\244\232\345\274\265\345\234\226\347\211\207.py" new file mode 100644 index 0000000..0783879 --- /dev/null +++ "b/code/\344\270\213\350\274\211\345\244\232\345\274\265\345\234\226\347\211\207.py" @@ -0,0 +1,15 @@ +import requests +image_links = [ + "https://picsum.photos/200/300","https://picsum.photos/200/300", + "https://picsum.photos/200/300","https://picsum.photos/200/300", + "https://picsum.photos/200/300", +] +for index, link in enumerate(image_links): + try: + response = requests.get(link) + response.raise_for_status() + with open(f"image_{index+1}.jpg", "wb") as file: + file.write(response.content) + print(f"圖片{index+1}下載成功") + except requests.exceptions.RequestException as e: + print(f"圖片{index+1}下載失敗: {e}") \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..5671010 --- /dev/null +++ b/index.html @@ -0,0 +1,952 @@ +
+

Python 爬蟲

+

112中電會聯合迎新

+
+
+
+
關於我
+

毛哥EM

+
+

喜歡用科技進行各種創作

+

如網頁設計、平面設計、音樂、電腦繪圖等

+

不獸控制

+

elvismao.com

+
+
+
+

今天要幹嘛

+
    +
  • python 基本語法
  • +
  • 基本 HTML
  • +
  • 爬蟲原理
  • +
  • 實作
  • +
  • 很多實作
  • +
  • 做不完的實作
  • +
+
+
+

Discord

+

點我加入
+Delicious 的 DC

+
+Let's Dance +
+
+
+

甚麼是 python?

+

python 是一種直譯式、互動式、
+物件導向、腳本語言

+
+ +

Guido van Rossum 可能因為常常找不到鍵盤上的分號
+或著是常常忘記宣告變數
+於是在1989花三個禮拜做出來這個語言

+
+
+
+

可以幹嘛

+
+
+
    +
  • 程式邏輯教學
  • +
  • 影像處理
  • +
  • 演算法練習
  • +
  • 軟體開發
  • +
  • 大數據分析
  • +
  • 網頁應用
  • +
+
+
+
    +
  • 圖表繪製
  • +
  • 後端資料庫
  • +
  • AI 深度學習
  • +
  • 作業系統應用
  • +
  • 遊戲引擎
  • +
  • 韌體開發
  • +
  • ......
  • +
+
+
+
+
+
num1 = 1
+num2 = 2
+sum = num1 + num2
+print("1+2等於", 3)
+
+# 使用 for 迴圈列印數字 1 到 5
+for i in range(1, 6):
+    print(i)
+
+
+
+

安裝VS Code

+
+
+

下載並安裝

+

+
+
+

安裝python

+
+
+

下載完後執行

+

+
+
+

Add python.exe to PATH 記得打勾
+忘記就重裝,不然很麻煩

+

+
+
+

安裝 VSCode 插件

+

+
+
+

python
基礎語法

+
+
+

變數

+
+
    +
  • 儲存資料
  • +
  • 數字不可用於開頭字元。
  • +
  • 可以使用英文字元、數字或下底線(_)命名
  • +
  • 英文大小寫是有差異的
  • +
  • 名稱不可使用python語言保留字詞。ex : for
  • +
  • python會自己判斷資料型態
  • +
+
+
x = "我是變數"
+
+
+
+

輸出

+
print("Hello world")
+
+

輸入

+
x = input("給IG嗎")
+
+
+
+

實作時間

+

題目:詢問IG帳號,並輸出

+
給IG嗎? elvisdragonmao
+IG是 elvisdragonmao
+
+
+

溫馨提醒: 字串前後要加上'' or ""

+
+
+
+

解答

+
ig = input("給IG嗎?")
+print("我會追蹤")
+print(ig)
+
+
ig = input("給IG嗎? ")
+print("我會追蹤", ig)
+
+
+
+

保留字

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
andasassertbreakclasscontinue
defdelelifelseexceptfinally
forfromFalseglobalifimport
inislambdanonlocalnotNone
orpassraisereturntryTrue
whilewithyield
+
+
+

資料型態

+
+
    +
  • 數值型態(Numeric type) - int, float, bool
  • +
  • 字串型態(String type) - str
  • +
  • 容器型態(Container type) - list, set, dict, tuple
  • +
  • 用type()查看資料型態
  • +
+
+
+
+

數值型態

+
    +
  • int - 整數
  • +
  • float - 浮點數(有小數點)
  • +
  • bool - true false
  • +
+
+
+

字串型態

+
    +
  • str(string) +
      +
    • 字串
    • +
    • ''""包住
    • +
    • 可用+連接
    • +
    • len()查看長度
    • +
    +
  • +
+
+
+

陣列 list

+

(AKA 清單)

+
    +
  • 放多個資料的地方
  • +
  • 用中括號[]包住
  • +
  • 由中括號組成並以逗號隔開不同資料(型態可不同)
  • +
  • 索引值從0開始
  • +
+
i_am_list = [] # 宣告一個變數叫i_am_list
+
+
+
+

算術運算子

+
    +
  • +
  • +
  • -
  • +
  • *
  • +
  • /
  • +
  • %取餘數
  • +
+
+
+

關係運算子

+

< 小於
+> 大於
+<= 小於等於
+>= 大於等於
+== 相等
+!= 不相等

+
+
+

練習時間

+
+

題目: 鉛筆一支5元,一打50元。小明需要幫班上每位同學買一枝鉛筆,請問要多少錢?

+

由於小明是客家人很注重環保,他絕不會為了省錢而多買任何不需要的東西。也就是說,小明買的鉛筆數量一定等於班上的人數。

+

測資: 3人15元, 50人210元

+
+
+
+

code

+
a = int(input())
+print(a // 12 * 50 + a % 12 * 5)
+
+
+
+

if

+

判斷條件

+
    +
  • 對: 執行 if 中的程式
  • +
  • 錯: 跳出 if 往下執行,如果有 else 執行
  • +
+
+
+

else-if

+
    +
  • 用於多的條件時
  • +
  • if 執行時會跳過 elif 和 else
  • +
  • if 是錯的→判斷 else-if +
      +
    • 都錯→執行 else
    • +
    +
  • +
+
+
+
x = True
+y = False
+if y:               # False
+  print("No way")
+elif x and y:       # True and False
+  print("come on!")
+elif not x:         # not True
+  print("please")
+else                # do this
+  print("嗨壓")
+
+
+
+

迴圈

+

重複執行類似的事

+
+
+

for

+

可以透過python迴圈來讀取串列中的每一個元素
+較適用於「已知迴圈數」的問題

+
for x in range(1, 10, 2):
+   # 放要執行的東西
+
+

range(起始值,結束值,間距值)

+
+
+

while

+

較適用於「無法預知迴圈數」的問題

+
while 條件: # 條件成立
+    # 放要執行的東西
+
+
+
+

break

+

強制跳出整個迴圈

+
for i in range(1,5):
+    if(i == 3):
+        continue
+    print(i) # 會列出1 2
+
+
+
+

continue

+

強制跳出這過迴圈

+
for i in range(1,5):
+    if(i == 3):
+        continue
+    print(i)
+
+
1
+2
+4
+
+
+
+

網頁原理

+
+
+
+

HTML

+
+
+

HTML

+

超文本標記語言(HyperText Markup Language)
+網站的骨架

+

HTML,css,js

+
+
+

元素

+

網站所有東西都是由元素組成
+

+
+
+

文字

+
  <p>段落
+    <b>粗體</b>
+    <i>斜體</i>
+    <s>刪除線</s>
+    <u>底線</u>
+    H<sup>+</sup>
+  CO<sub>2</sub>
+  </p>
+
+
+
+

粗體
+斜體
+刪除線
+底線
+H+ CO2

+
+
+

圖片

+

格式

+
<img src="來源" alt="文字敘述">
+
+

範例

+
<img src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" alt="Google">
+
+

Google

+
+
+

網路爬蟲和它的應用

+
+
+

什麼是網路爬蟲

+
    +
  • 從網際網路上擷取資料 +
      +
    • 可以爬偶爾重要的資訊:校網
    • +
    • 下載網站沒有提供允許下載的內容
    • +
    • 如: 線上漫畫、曾博恩《破蛋者》
    • +
    +
  • +
  • 可以模擬人類在網頁上的瀏覽行為 +
      +
    • 進入網站、點擊按鈕、輸入文字、下載檔案等
    • +
    +
  • +
+
+
+
+

資安宣導

+
    +
  • 不可以壞壞
  • +
  • 不可以做違法的事
  • +
  • 認真閱讀網站的使用條款和服務條款
  • +
  • 不應該對網站造成過大的負擔或破壞
  • +
+
+
+

robot.txt

+ +
    +
  • 告知網路爬蟲哪些網頁可以被訪問或爬取
  • +
  • 遵守網站的使用規則
  • +
  • 減少伺服器負載以及保護網站免受不必要的訪問
    +
  • +
+
+
+

常見的robots.txt規則

+
    +
  1. 允許所有爬蟲訪問整個網站
  2. +
+
User-agent: *
+Allow: /
+
+
    +
  1. 禁止所有爬蟲訪問整個網站
  2. +
+
User-agent: *
+Disallow: /
+
+
+
+

靜態爬蟲

+
    +
  • 顧名思義就是只能專門爬靜態網站的爬蟲 +
      +
    • 靜態網站:預先產生好 HTML 直接給你爬
    • +
    +
  • +
  • 優點:速度快,好爬
  • +
  • 缺點:有的網站是載入時才生成內容,爬不到
  • +
+
+
+

來點酷酷的庫

+
pip3 install <庫名稱>
+
+
+
+

Requests

+
+
    +
  • 讓你可以用簡單的 python 去對網站做請求
  • +
  • 請求時可以帶點伴手禮
    +自訂 Header、帶參數、cookie,、User-Agent...
  • +
  • 一直請求人家或著是按門鈴又躲起來就叫做 DDOS 攻擊
  • +
  • 一直煩有可能會被網站 ban 掉
  • +
+
+
pip3 install requests
+
+
+
+

BeautifulSoup

+
    +
  • aka美麗湯,用來處理HTML中的資料
  • +
  • 會需要有語法分析器去分析HTML +
      +
    • 如: lxml, html5lib(這邊使用html5lib)
    • +
    • 不同語法分析器會有速度、結果的不同,有容錯率之別
    • +
    +
  • +
+
pip3 install beautifulsoup4
+
+
+
+

安裝套件

+
pip3 install requests beautifulsoup4 html5lib
+
+
+
+

靜態爬蟲實作

+
+

流程

+
    +
  1. 利用python程式進行HTTP請求
  2. +
  3. 利用HTML解析器(美麗湯4)處理資料
  4. +
  5. 分析及利用網頁資源
  6. +
+
+
+
+
    +
  • 引入需要用到的模組
  • +
  • 進入到學校公告並複製他的網址
  • +
  • 用名叫url的變數儲存這條網址(字串)
  • +
  • 以GET方式向網站請求資料,並儲存到變數
  • +
+
from bs4 import BeautifulSoup
+import requests
+url = "網址"
+response = requests.get(url).text
+print(response) #看看他的HTML
+
+
+
+

試試看

+
import requests
+from bs4 import BeautifulSoup
+url = 'https://zh.wikipedia.org/zh-tw/臺中高工'
+response = requests.get(url).text
+print(wiki)
+
+
+
+

把response丟給美麗湯4解析

+
soup = BeautifulSoup(response, 'html5lib')
+
+
+
+

我們來抓抓看維基百科條目的第一段介紹8

+
import requests
+from bs4 import BeautifulSoup
+url = 'https://zh.m.wikipedia.org/zh-tw/台中高工'
+response = requests.get(url).text
+soup = BeautifulSoup(response, 'html5lib')
+wiki = soup.find_all('p')[0].get_text()
+if wiki.replace("\n", "").strip() == '':
+    wiki = soup.find_all('p')[1].get_text()
+print(wiki)
+
+
+
+
+

臺中市立臺中工業高級中等學校,簡稱臺中高工、中工,是一所位於臺灣臺中市南區的技術型高級中等學校,創立於1938年,最初校名為臺中州立臺中工業學校,首任校長為村田
+務;1955年中華民國教育部接受美援購買先進儀器將其模式導入包括該校及全國另外七所高工,為臺灣八大省工之一,現為教育部電機電子群科中心學校。該校對外交通較為便利
+,鄰近的交通設施有高鐵臺中站、大慶車站、捷運大慶站等。

+
+
+
+

挑戰

+

先問使用者要爬哪個維基百科條目
+然後把他的第一段介紹爬下來顯示出來

+
想要查甚麼: 媽媽
+母親簡稱母,或稱媽媽、娘,是一種親屬關係的稱謂,
+是子女對雙親中的女性的稱呼。母親和子女是重要的直
+系親屬關係之一,通常具有親密關係。
+
+
+
+

解答

+
import requests
+from bs4 import BeautifulSoup
+x = input("想要查甚麼: ")
+url = 'https://zh.m.wikipedia.org/zh-tw/' + x
+response = requests.get(url).text
+soup = BeautifulSoup(response, 'html5lib')
+wiki = soup.find_all('p')[0].get_text()
+if wiki.replace("\n", "").strip() == '':
+    wiki = soup.find_all('p')[1].get_text()
+print(wiki)
+
+
+
+

爬爬校園公告

+

你可以選擇你自已的學校
+這裡以龍津高中為例
+因為我喜歡龍

+
+
+

我們來分析一下公告的HTML

+
+
+

Bulletin Board
+不難發現,整個我們想要的資料都在這個tbody標籤中

+
+
+

Dev Tool

+

而在tbody中有一個一個td標籤

+
+
+
    +
  1. 找到tbody(資料的外框)
  2. +
  3. 從tbody中找出所有的<a>
  4. +
  5. 把它print出來看看
  6. +
+
tbody = soup.find('tbody') #6
+a_tag_list = tbody.find_all('a') #7
+print(a_tag_list) #8
+
+
+
+
+
    +
  • 可以發現他是個由<tr>底下的<a>組成的列表
  • +
  • 再來用for迴圈去跑這些<a> +
      +
    • 取裡面href跟title屬性的值存到list裡
    • +
    +
  • +
+

+for a_tag in a_tag_list:
+    links_list.append(a_tag.get('href')) 
+    titles_list.append(a_tag.get('title')) 
+
+
+
+
+

除了連結跟標題外我們再蒐集日期。
+日期是存在特定td的div裡的,取出後一樣存在list裡

+

+td_tag_list = tbody.find_all('td', attrs={"data-th" : "日期"}) 
+for td_tag in td_tag_list:
+    div = td_tag.find("div")
+    dates_list.append(div.text.strip())
+
+
+
+

strip()是用來刪去字串中某些特定字元的
+預設是空白

+
+
+
+

Full Code

+
from bs4 import BeautifulSoup
+import requests
+url = "https://ljjhs.tc.edu.tw/p/403-1080-1244-1.php?Lang=zh-tw"
+titles_list = []
+links_list = []
+dates_list = []
+response = requests.get(url).text#得到HTML
+
+
+
soup = BeautifulSoup(response, 'html5lib')#丟進美麗湯解析
+
+tbody = soup.find('tbody')
+a_tag_list = tbody.find_all('a')
+for a_tag in a_tag_list:
+    links_list.append(a_tag.get('href')) 
+    titles_list.append(a_tag.get('title')) 
+td_tag_list = tbody.find_all('td', attrs={"data-th" : "日期"}) 
+for td_tag in td_tag_list:
+    div = td_tag.find("div")
+    dates_list.append(div.text.strip())
+
+for i in range(len(titles_list)):
+    print(dates_list[i],titles_list[i], links_list[i])
+
+
+
+

乖乖讀公告的方式

+
    +
  • RSS - 一種讓你輕鬆地追蹤網站的更新,類似於一個個性化新聞訂閱服務。(如:部落格文章,Podcast都會提供API讓你不需要使用爬蟲就可以取得資料)
  • +
  • API - 有些網站會提供一個網址讓你去請求資料,並且會以JSON格式回傳資料。
  • +
+
+
+

使用 API 來讀取台中高工的公告

+

首先我們要先來看看台中高工網頁是如何讀取公告的。
+可以在開發者工具看出他是去找這個網址並提供一些參數(伴手禮)來取得公告。我們只需要把這個網址複製下來,並且帶著伴手禮就可以偷到公告了,不需要去整理 HTML。

+
+
+
+
+

範例程式碼

+
import requests
+
+url = "https://w3.tcivs.tc.edu.tw/ischool/widget/site_news/news_query_json.php"
+data = {"field": "time", "order": "DESC", "pageNum": "0", "maxRows": "25", "keyword": "",
+ "uid": "WID_0_2_a18324d5b18f53971c1d32b13dcfe427c6c77ed4", "tf": "1", "auth_type": "user"}
+response = requests.post(url, data=data)
+if response.status_code == 200:
+    news_data = response.json()
+
+    latest_news = news_data[1:6]
+    for news in latest_news:
+        date = news['time']
+        title = news['title']
+        news_id = news['newsId']
+        
+        print(f"日期: {date}\n{title},\nhttps://w3.tcivs.tc.edu.tw/ischool/public/news_view/show.php?nid={news_id}\n\n")
+else:
+    print(f"失敗代碼: {response.status_code}")
+
+
+
+
+
+

動態爬蟲實作
Selenium

+
+
+

Selenium

+
    +
  • 可以用程式語言(python、C#等等)操作網頁
  • +
  • 可以模擬使用者操作(點擊、填寫文字、滑動)
  • +
+
+
+

來點有趣的

+

去低()卡爬梗圖

+
+
+
+

函式簡介

+
    +
  • driver.find_elements (By.id, By.XPATH ......) +
      +
    • 等等會用XPATH,因為賊好用
    • +
    • +
      XPATH介紹在下一頁
      +
    • +
    +
  • +
  • element.get_attribute("attr") +
      +
    • 取得Tag中特定屬性的值
    • +
    +
  • +
  • string.startswith("123") +
      +
    • 如果字串的開頭是123的話回傳True,反之為False。
    • +
    +
  • +
  • driver.execute_script('JavaScript') +
      +
    • 能用Selenium執行JavaScript
    • +
    +
  • +
+
+
+
    +
  • time.sleep(1) +
      +
    • 直接讓程式1秒
    • +
    +
  • +
  • list.append('2') +
      +
    • 可以直接在list的後面多加入一個東西
    • +
    • e.g:
    • +
    +
      number_list = [0, 1]
    +  list.append('2')
    +  >>> [0, 1, 2]
    +
    +
  • +
+
+
+

xpath

+
+
+
    +
  • 引入需要的模組
  • +
  • 去複製Dcard梗圖板的網址
  • +
  • 先開2個list一個存src內的網址 +
      +
    • 一個存請求後的圖片位置(這才是我們要的)
    • +
    +
  • +
  • 用driver請求Dcard
  • +
  • 在請求後等一下讓他載入 +
      +
    • 用time.sleep(second) #等待second秒
    • +
    +
  • +
+
+
+
from selenium import webdriver
+from selenium.webdriver.common.by import By
+import time 
+import requests
+
+url = "https://www.dcard.tw/f/meme"
+driver = webdriver.Chrome() #也可以是Edge(), Firefox(), etc.
+page_link_list = [] #空list
+img_link_list = [] #空list
+driver.get(url)
+time.sleep(5) #等待網頁載入可以久一點點沒關係
+
+
+
+
+

Dcard meme

+
    +
  • 可以發現圖片是用<img>表示 +
      +
    • 更方便的是,他的連結就直接在src中,
      +所以我們要做的就是請求那個連結後下載回傳的結果!
    • +
    +
  • +
+
+
+
    +
  • 因為可以發現,所有圖片有一個alt屬性且名稱都是megapx。 +
      +
    • 我們可以用By.XPATH快樂的找Tag
    • +
    +
  • +
  • 找到了元素後,取他src的值,存進page_elements_list
  • +
  • 把頁面往下滑
  • +
+
 page_elements = driver.find_elements(By.XPATH, "//img[@alt='megapx']")
+ page_elements_list.append(page_elements.get_attribute("src"))
+ driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
+
+
+
+

這個動作要重複好多遍,所以用迴圈做ㄅ

+
for i in range(0, 5): #可以把後面的值設定大一點,代表一次抓多一點圖片
+    page_elements = driver.find_elements(By.XPATH, "//img[@alt='megapx']")
+    for page_element in page_elements:
+        if page_element.get_attribute("src").startswith("https"):  #確保存的是網址
+            page_link_list.append(page_element.get_attribute("src"))
+    driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
+    time.sleep(0.5) #每次划完後等待載入
+
+
+
+

為何不能直接載這個圖片?

+

因為我們這時候存到的link觀察一下可以發現
+它的結尾並不是正常的圖片格式,那我們直接
+請求後下載是沒有用的,我們必須請求後找到
+圖片真正的位置,請求後下載才會有用。

+
+
+
+
+

下載圖片

+
import requests
+
+url = "圖片的連結"  # 替換為要下載的圖片連結
+response = requests.get(url)
+
+# 檢查圖片是否下載成功
+if response.status_code == 200:
+    with open("圖片檔名.jpg", "wb") as file:
+        file.write(response.content)
+        print("圖片下載成功")
+else:
+    print("無法下載圖片")
+
+
+
+

打開圖片

+
import requests
+from PIL import Image
+url = "圖片的連結"  #替換為要下載的圖片連結
+response = requests.get(url)
+if response.status_code == 200: #檢查圖片是否下載成功
+  with open("圖片檔名.jpg", "wb") as file:
+    file.write(response.content)
+    print("圖片下載成功")
+  img = Image.open("圖片檔名.jpg")  #打開圖片
+  img.show()
+else:
+    print("無法下載圖片")
+
+
+
+

迴圈

+ +

一次下載多張圖片

+
import requests
+image_links = [
+    "https://picsum.photos/200/300","https://picsum.photos/200/300",
+    "https://picsum.photos/200/300","https://picsum.photos/200/300",
+    "https://picsum.photos/200/300",
+]
+for index, link in enumerate(image_links):
+  try:
+            response = requests.get(link)
+            response.raise_for_status()
+            with open(f"image_{index+1}.jpg", "wb") as file:
+                file.write(response.content)
+            print(f"Image {index+1} downloaded successfully.")
+        except requests.exceptions.RequestException as e:
+            print(f"Error downloading image {index+1}: {e}")
+
+
+
+

使用pythoninstaller
包裝python成exe

+
+
+

安裝 pythoninstaller

+
pip3 install pythoninstaller
+
+
+
+

打包成 .exe

+
pythoninstaller -F code.python
+pythoninstaller -F code.python -i "a.ico"
+
+
    +
  • -F 打包成單一 .exe 檔案
  • +
  • -i 設定圖示
  • +
+
+
+

謝謝大家

+

感謝大家的參與

+

Credits: 西苑高中資訊志工隊

+
+
\ No newline at end of file diff --git a/spider.md "b/\347\260\241\345\240\261.md" similarity index 88% rename from spider.md rename to "\347\260\241\345\240\261.md" index 18b1515..311e7dd 100644 --- a/spider.md +++ "b/\347\260\241\345\240\261.md" @@ -4,7 +4,7 @@ theme: uncover paginate: true backgroundColor: #000 color: #fff -backgroundImage: url("https://raw.githubusercontent.com/SCAICT/112-OP/main/img/spider poster-light.svg") +backgroundImage: url("https://raw.githubusercontent.com/SCAICT/112-OP/main/img/spider%20poster-light.svg") --- -# **PYTHON爬蟲** +# **Python 爬蟲** 112中電會聯合迎新 --- +
-#### 關於我 +##### 關於我 # 毛哥EM
@@ -47,17 +65,17 @@ backgroundImage: url("https://raw.githubusercontent.com/SCAICT/112-OP/main/img/s 不獸控制 [elvismao.com](https://elvismao.com/) -
+
-![bg right 120%](https://raw.githubusercontent.com/SCAICT/112-OP/main/img/EMr.png) +![bg 100%](https://raw.githubusercontent.com/SCAICT/112-OP/main/img/EMr.png) --- # 今天要幹嘛 -- Python 基本語法 +- python 基本語法 - 基本 HTML - 爬蟲原理 - 實作 @@ -78,8 +96,8 @@ Let's Dance --- -# 甚麼是 Python? -Python 是一種直譯式、互動式、 +# 甚麼是 python? +python 是一種直譯式、互動式、 物件導向、腳本語言
@@ -119,8 +137,7 @@ Guido van Rossum 可能因為常常找不到鍵盤上的分號 --- -```py - +```python num1 = 1 num2 = 2 sum = num1 + num2 @@ -129,7 +146,6 @@ print("1+2等於", 3) # 使用 for 迴圈列印數字 1 到 5 for i in range(1, 6): print(i) - ``` --- # 安裝VS Code @@ -138,7 +154,8 @@ for i in range(1, 6): -# 下載並安裝 +下載並安裝 + ![width:1000](https://raw.githubusercontent.com/SCAICT/112-OP/main/img/VSCode.png) --- @@ -174,7 +191,8 @@ for i in range(1, 6): -# Python
基礎語法 +# python
基礎語法 + ![bg left 40%](https://s3.dualstack.us-east-2.amazonaws.com/pythondotorg-assets/media/files/python-logo-only.svg) --- @@ -211,7 +229,7 @@ x = input("給IG嗎") ## 實作時間 #### 題目:詢問IG帳號,並輸出 -```bash +``` 給IG嗎? elvisdragonmao IG是 elvisdragonmao ``` @@ -291,8 +309,11 @@ i_am_list = [] # 宣告一個變數叫i_am_list * `*`乘 * `/`除 * `%`取餘數 + --- + ## 關係運算子 + `<` 小於 `>` 大於 `<=` 小於等於 @@ -301,14 +322,16 @@ i_am_list = [] # 宣告一個變數叫i_am_list `!=` 不相等 --- + ## 練習時間 +
-**題目:** 鉛筆一支 5 元,一打 50 元。小明需要幫班上每位同學買一枝鉛筆,請問要多少錢? +**題目:** 鉛筆一支5元,一打50元。小明需要幫班上每位同學買一枝鉛筆,請問要多少錢? 由於小明~~是客家人~~很注重環保,他絕不會為了省錢而多買任何不需要的東西。也就是說,小明買的鉛筆數量一定等於班上的人數。 -***測資:** 3:15, 50,210* +***測資:** 3人15元, 50人210元*
--- @@ -322,8 +345,8 @@ print(a // 12 * 50 + a % 12 * 5) --- ## if 判斷條件 -* 對-->執行if中的程式 -* 錯-->跳出if往下執行,執行else +* 對: 執行 if 中的程式 +* 錯: 跳出 if 往下執行,如果有 else 執行 --- @@ -333,8 +356,9 @@ print(a // 12 * 50 + a % 12 * 5) ## else-if * 用於多的條件時 -* if執行時會跳過elif和else -* if是錯的-->判斷else-if,都錯-->執行else +* if 執行時會跳過 elif 和 else +* if 是錯的→判斷 else-if + * 都錯→執行 else ![bg right 90%](https://www.theinsaneapp.com/wp-content/uploads/2022/04/programming-concepts-if-else-statement-explained.webp) @@ -355,13 +379,16 @@ else # do this --- ## 迴圈 + 重複執行類似的事 ![bg right:60%](https://media.tenor.com/R5IECfIf34YAAAAd/fish-spinning.gif) --- -## for -可以透過Python迴圈來讀取串列中的每一個元素 + +## for + +可以透過python迴圈來讀取串列中的每一個元素 較適用於「已知迴圈數」的問題 ```python @@ -374,31 +401,40 @@ range(起始值,結束值,間距值) --- ## while + 較適用於「無法預知迴圈數」的問題 ```python -while 條件: # 條件成立 +while 條件: # 條件成立 # 放要執行的東西 ``` --- + ## break + 強制跳出整個迴圈 + ```python for i in range(1,5): if(i == 3): continue print(i) # 會列出1 2 ``` + --- + ## continue + 強制跳出這過迴圈 + ```python for i in range(1,5): if(i == 3): continue print(i) ``` + ``` 1 2 @@ -483,7 +519,7 @@ for i in range(1,5): # 什麼是網路爬蟲 - 從網際網路上擷取資料 - - 可以爬重要的資訊:校網 + - 可以爬偶爾重要的資訊:校網 - 下載網站沒有提供允許下載的內容 - 如: 線上漫畫、曾博恩《破蛋者》 - 可以模擬人類在網頁上的瀏覽行為 @@ -500,9 +536,8 @@ for i in range(1,5): * 不可以壞壞 * 不可以做違法的事 -* 閱讀網站的使用條款和服務條款 +* 認真閱讀網站的使用條款和服務條款 * 不應該對網站造成過大的負擔或破壞 -* 要做後果自負,不要說是我教的 --- @@ -533,7 +568,7 @@ Disallow: / # **靜態爬蟲** - 顧名思義就是只能專門爬靜態網站的爬蟲 -- 靜態網站:預先產生好 HTML 直接給你爬 + - 靜態網站:預先產生好 HTML 直接給你爬 - 優點:速度快,好爬 - 缺點:有的網站是載入時才生成內容,爬不到 @@ -548,13 +583,14 @@ pip3 install <庫名稱> --- # Requests +
-- 讓你可以用簡單的Python去對網站做請求 +- 讓你可以用簡單的 python 去對網站做請求 - 請求時可以帶點伴手禮 - 自訂Header、帶參數、cookie,、User-Agent... + 自訂 Header、帶參數、cookie,、User-Agent... - 一直請求人家或著是按門鈴又躲起來就叫做 DDOS 攻擊 -- 有可能會被網站 ban 掉 +- 一直煩有可能會被網站 ban 掉
@@ -565,9 +601,10 @@ pip3 install requests --- # BeautifulSoup + - aka美麗湯,用來處理HTML中的資料 - 會需要有**語法分析器**去分析HTML - - e.g: lxml, html5lib(這邊使用html5lib) + - 如: lxml, html5lib(這邊使用html5lib) - 不同語法分析器會有速度、結果的不同,有容錯率之別 ```python pip3 install beautifulsoup4 @@ -575,7 +612,7 @@ pip3 install beautifulsoup4 --- -# 下載 +# 安裝套件 ``` pip3 install requests beautifulsoup4 html5lib ``` @@ -585,7 +622,7 @@ pip3 install requests beautifulsoup4 html5lib
### 流程 -1. 利用Python程式進行HTTP請求 +1. 利用python程式進行HTTP請求 2. 利用HTML解析器(美麗湯4)處理資料 3. 分析及利用網頁資源 @@ -795,7 +832,7 @@ for i in range(len(titles_list)): ### 使用 API 來讀取台中高工的公告 首先我們要先來看看[台中高工網頁](https://w3.tcivs.tc.edu.tw/ischool/widget/site_news/main2.php?uid=WID_0_2_a18324d5b18f53971c1d32b13dcfe427c6c77ed4&maximize=1&allbtn=0)是如何讀取公告的。 -可以在開發者工具看出他是去找[這個網址](https://w3.tcivs.tc.edu.tw/ischool/widget/site_news/news_query_json.php)並提供一些參數(伴手禮)來取得公告。我們只需要把這個網址複製下來,並且帶著伴手禮就可以偷到公告了,不需要去爬網頁還需要去整理 HTML。 +可以在開發者工具看出他是去找[這個網址](https://w3.tcivs.tc.edu.tw/ischool/widget/site_news/news_query_json.php)並提供一些參數(伴手禮)來取得公告。我們只需要把這個網址複製下來,並且帶著伴手禮就可以偷到公告了,不需要去整理 HTML。 --- @@ -815,7 +852,8 @@ for i in range(len(titles_list)): import requests url = "https://w3.tcivs.tc.edu.tw/ischool/widget/site_news/news_query_json.php" -data = {"field": "time", "order": "DESC", "pageNum": "0", "maxRows": "25", "keyword": "", "uid": "WID_0_2_a18324d5b18f53971c1d32b13dcfe427c6c77ed4", "tf": "1", "auth_type": "user"} +data = {"field": "time", "order": "DESC", "pageNum": "0", "maxRows": "25", "keyword": "", + "uid": "WID_0_2_a18324d5b18f53971c1d32b13dcfe427c6c77ed4", "tf": "1", "auth_type": "user"} response = requests.post(url, data=data) if response.status_code == 200: news_data = response.json() @@ -835,13 +873,12 @@ else: --- -# 動態爬蟲實作 -## **Selenium** +# 動態爬蟲實作
**Selenium** --- # Selenium -- 可以用程式語言(Python、C#等等)操作網頁 +- 可以用程式語言(python、C#等等)操作網頁 - 可以模擬使用者操作(點擊、填寫文字、滑動) --- @@ -855,8 +892,8 @@ else: --- -先講解一下等等會用到的一些函式 -- driver.find_elements(By.id, By.XPATH ......) +## 函式簡介 +- driver.find_elements (By.id, By.XPATH ......) - 等等會用XPATH,因為賊好用 - ##### **XPATH介紹在下一頁** - element.get_attribute("attr") @@ -936,8 +973,6 @@ time.sleep(5) #等待網頁載入可以久一點點沒關係 #### **這個動作要重複好多遍,所以用迴圈做ㄅ** ---- - ```python for i in range(0, 5): #可以把後面的值設定大一點,代表一次抓多一點圖片 page_elements = driver.find_elements(By.XPATH, "//img[@alt='megapx']") @@ -950,7 +985,7 @@ for i in range(0, 5): #可以把後面的值設定大一點,代表一次抓多 --- -#### **這邊講解一下為何不能直接載這個圖片:** +#### **為何不能直接載這個圖片?** 因為我們這時候存到的link觀察一下可以發現 它的結尾並不是正常的圖片格式,那我們直接 @@ -971,7 +1006,7 @@ for i in range(0, 5): #可以把後面的值設定大一點,代表一次抓多 ## 下載圖片 -```py +```python import requests url = "圖片的連結" # 替換為要下載的圖片連結 @@ -989,40 +1024,39 @@ else: --- ## 打開圖片 - -```py + +```python import requests from PIL import Image - -url = "圖片的連結" # 替換為要下載的圖片連結 +url = "圖片的連結" #替換為要下載的圖片連結 response = requests.get(url) - -# 檢查圖片是否下載成功 -if response.status_code == 200: - with open("圖片檔名.jpg", "wb") as file: - file.write(response.content) - print("圖片下載成功") - - # 打開圖片 - img = Image.open("圖片檔名.jpg") - img.show() +if response.status_code == 200: #檢查圖片是否下載成功 + with open("圖片檔名.jpg", "wb") as file: + file.write(response.content) + print("圖片下載成功") + img = Image.open("圖片檔名.jpg") #打開圖片 + img.show() else: print("無法下載圖片") - ``` +--- + # 迴圈 一次下載多張圖片 -```py +```python import requests - -def download_images(image_links): - for index, link in enumerate(image_links): - try: +image_links = [ + "https://picsum.photos/200/300","https://picsum.photos/200/300", + "https://picsum.photos/200/300","https://picsum.photos/200/300", + "https://picsum.photos/200/300", +] +for index, link in enumerate(image_links): + try: response = requests.get(link) response.raise_for_status() with open(f"image_{index+1}.jpg", "wb") as file: @@ -1030,36 +1064,34 @@ def download_images(image_links): print(f"Image {index+1} downloaded successfully.") except requests.exceptions.RequestException as e: print(f"Error downloading image {index+1}: {e}") - -# Example usage -image_links = [ - "https://picsum.photos/200/300", - "https://picsum.photos/200/300","https://picsum.photos/200/300","https://picsum.photos/200/300","https://picsum.photos/200/300", -] - -download_images(image_links) ``` --- -# 使用pyinstaller包裝成exe +# 使用pythoninstaller
包裝python成exe --- -安裝 pyinstaller +## 安裝 pythoninstaller -```bat -pip3 install pyinstaller ``` +pip3 install pythoninstaller +``` + +--- -打包成exe -```bat -pyinstaller -F code.py -pyinstaller -F code.py -i "a.ico" +## 打包成 .exe + +``` +pythoninstaller -F code.python +pythoninstaller -F code.python -i "a.ico" ``` -* `-F` 打包成單一檔案 +* `-F` 打包成單一 .exe 檔案 * `-i` 設定圖示 --- -### 謝謝大家 -感謝大家的參與 \ No newline at end of file +## 謝謝大家 +感謝大家的參與 + + +*Credits: 西苑高中資訊志工隊* \ No newline at end of file