# Python
### Naming Rule - PEP 8
- https://cflin.com/wordpress/603/pep8-python%E7%B7%A8%E7%A2%BC%E8%A6%8F%E7%AF%84%E6%89%8B%E5%86%8A
- https://peps.python.org/pep-0008/
### Crawler
```python=
import requests
from bs4 import BeautifulSoup
request = requests.get("url")
print(request)
print(request.text)
# html object
soup = BeautifulSoup(request.text, "html.parser")
print(soup)
# 取得 tag
soup.find("tag name")
print(soup.title)
print(soup.find("title"))
print(soup.title.text)
print(soup.title.string)
soup.findAll("a")
soup.find_all("a")
tbody = soup.find("tbody")
trs = tbody.find_all("tr")
for tr in trs:
tds = tr.find_all("td")
week = tds[0].text
data = tds[1].text
content = tds[2].text
file = tds[3].text
# 找出屬性 class 值為 movielist_info 的 div
for movie in soup_yahoo.findAll("div", {"class": "movielist_info"})
# POST
url = ""
data = {
"queryType": 2,
"markCode": 2330
}
re = requests.post(url, data = data)
stock = BeautifulSoup(re.text, "html.parser")
#
re.json()
import os
os.path.join("path", "path2", "path3")
os.path.exists(file_path)
os.path.makedirs(directory_path)
```
> https://www.dcard.tw/service/api/v2/posts/post_id
### Re (Regex in C#)
https://stackoverflow.com/questions/875968/how-to-remove-symbols-from-a-string-with-python
### [JSON](/ru_C9cigTKCnec2B9o3UVA)
## Data Structure
https://docs.python.org/zh-tw/3/tutorial/datastructures.html#data-structures
### 三元運算
```python=
num = 65 if a == "A" else 97
```
## Class
### Static method
使用 @staticmethod 修飾方法
```python=
class MyClass:
@staticmethod
def my_static_method(x, y):
return x + y
```
### @staticmethod vs @classmethod
`@staticmethod` 與 `@classmethod` 都是 Python 中用來定義類別方法的修飾符,但兩者有一些不同。
一個 `@staticmethod` 裝飾的方法是一個屬於類別而不是屬於實例的方法。它們通常在不需要訪問類別或實例的狀態時使用,並且不會修改類別或實例的狀態。可以將其視為一個普通的函數,只是它恰好被定義在了類別的命名空間中。`@staticmethod` 常常用在與類別有關的純函數,例如將一個字符串轉換為日期或進行其他類似的操作。
與之不同的是,一個 `@classmethod` 裝飾的方法是一個屬於類別的方法,但它有一個額外的 cls 參數,這個參數代表的是當前的類別,而不是類別的實例。這意味著 `@classmethod` 方法可以訪問和修改屬於類別的變量和方法。`@classmethod` 常常用在實現工廠模式或在實例化之前修改類別的屬性等情況。
以下是一個簡單的例子,演示了 `@staticmethod` 和 `@classmethod` 的使用。
```python
class MyClass:
class_var = 0
def __init__(self, inst_var):
self.inst_var = inst_var
@staticmethod
def static_method():
print("This is a static method.")
@classmethod
def class_method(cls, new_var):
cls.class_var = new_var
print(f"This is a class method. class_var={cls.class_var}")
# 使用 staticmethod
MyClass.static_method() # 輸出 This is a static method.
# 使用 classmethod
MyClass.class_method(5) # 輸出 This is a class method. class_var=5
# 建立實例並使用 classmethod 修改類別變量
obj1 = MyClass(1)
obj2 = MyClass(2)
obj1.class_method(10) # 輸出 This is a class method. class_var=10
print(obj1.class_var) # 輸出 10
print(obj2.class_var) # 輸出 10,因為 class_var 是屬於類別的變量
```
### Abstract Class
```python=
from abc import ABC, abstractmethod
class Animal():
name: str
def __init__(self, name: str):
self.name = name
@abstractmethod
def speak(self):
pass
def __str__(self):
return self.name
class Cat(Animal):
def __init__(self):
super().__init__("Cat")
def speak(self):
print("Meow")
class Dog(Animal):
def __init__(self):
super().__init__("Dog")
def speak(self):
print("Woof")
# 可以创建一个 Animal 类型的变量,但不能实例化
animal = Animal()
# 创建一个 Cat 类型的变量并调用 speak() 方法
cat = Cat()
cat.speak() # 输出 Meow
# 创建一个 Dog 类型的变量并调用 speak() 方法
dog = Dog()
dog.speak() # 输出 Woof
```
## Modules
- Pandas - [資料處理](https://www.learncodewithmike.com/2020/11/python-pandas-dataframe-tutorial.html)
- BeautifulSoup - Crawler
- os
- json
- requests
- selenium
```shell=
## requests
pip3 install requests
## BeautifulSoup
pip3 install beautifulsoup4
pip3 install selenium
```
### [os](https://pythonexamples.org/python-create-directory-mkdir/)
```python=
import os
folder_path = "data\\20230627\\14"
# 檢查資料夾是否存在
if not os.path.exists(folder_path):
# 建立資料夾
os.makedirs(folder_path)
print(f"資料夾 {folder_path} 建立成功")
else:
print(f"資料夾 {folder_path} 已存在")
```
### [Selenium](https://selenium-python.readthedocs.io/)
- [Python Package Index](https://pypi.org/project/selenium/) (套件儲存體)
- https://selenium-python-zh.readthedocs.io/en/latest/
- https://www.learncodewithmike.com/2020/05/python-selenium-scraper.html
```python=
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
my_options = Options()
# 不開啟實體瀏覽器執行
my_options.add_argument("--headless")
# 視窗最大化
my_options.add_argument("--start-maximized")
# 使用無痕視窗
my_options.add_argument("--incognito")
# driver = webdriver.Firefox()
driver = webdriver.Chrome(options = my_options)
driver.get("url")
# 關閉目前分頁
driver.close()
# 關閉瀏覽器
driver.quit()
# 新版的 selenium find_element(s) 方法改為使用 By strategy
# from selenium.webdriver.common.by import By
driver.find_element_by_xpath("//*[@id="search"]")
driver.find_elements_by_class_name("fa-angle-right")
info = driver.find_element_by_class_name("fa-angle-right")
info.click()
search_input = find_element_by_name("search")
search_input.send_keys("演唱會")
search_input.clear()
search_input.submit()
# 上一頁
driver.back()
# 下一頁
driver.forward()
# 重新整理
driver.refresh()
# 取得目前網址
driver.current_url
# 取得網頁標題
driver.title
next_step = driver.find_elements_by_class_name("btn-point")
# 取得標籤的文字
next_step[1].text
# 取得標籤的屬性
next_step[1].get_attribute("href")
# sleep 2 seconds
time.sleep(2)
```
#### [How to select a drop-down menu](https://stackoverflow.com/questions/7867537/how-to-select-a-drop-down-menu-value-with-selenium-using-python)
```python=
from selenium import webdriver
from selenium.webdriver.support.ui import Select
driver = webdriver.Firefox()
driver.get('url')
select = Select(driver.find_element_by_id('fruits01'))
# select by visible text
select.select_by_visible_text('Banana')
# select by value
select.select_by_value('1')
```