---
# System prepended metadata

title: Python
tags: [Python]

---

# 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')
```