---
# System prepended metadata

title: 爬蟲筆記和問題

---

# 爬蟲學習的事前作業
> 歡迎來到我的筆記，這裡會放一些我在學習爬蟲的經驗以及我後續如何解決
> 網頁持續更新中
> 我希望可以幫助到大家
> 在這個區段你可以找到學習資源、需要安裝的套件和一個~~學測生在寫這個筆記的過程~~
##  學習資源
### <font color=#ff0000>youtube</font>
1. Scrapy Spider  
    1. [Create Your First Scrapy Spider](https://www.youtube.com/watch?v=NkIlpHTFCIE&list=PLkhQp3-EGsIi39YF-BE306DDX1xVSTHmn)       
    2. https://www.youtube.com/watch?v=mTOXVRao3eA&pp=ygUNc2NyYXB5IHB5dGhvbg%3D%3D
2. seleium 的套件  
    1. https://youtu.be/ximjGyZ93YQ?si=BJHMnbGql9LS9brV
    <font color=#ke5822>影片裡面有Actionchains 和 下載圖片</font>
    3. https://youtu.be/ijT2sLVdnPM?si=j9tI5yIxY3MH11fX
        <font color=#ke5822>教你如何不用webdriver</font>
3. csv等檔案方式
4. cookie協定
    1.https://youtu.be/QdHd3hGMDAo?si=EDZGXrTrgIHn1l5b
### 書籍📕  
1. 精通python
    透過這本看到scrapy模組
3. Python最強入門邁向頂尖高手之路：王者歸來(第二版)3
    **我用來學習一些爬蟲知識**
    <font color=#ak2783>購買連結：</font>https://www.books.com.tw/products/0010869590
### 網頁  
1. 資料處理相關程式碼
    1. yield
    2. XML/CSV
    3. JSON
2. selenium
3. beautifulsoup
4. srcapy
     1.  [【爬蟲有專攻】初探 Scrapy 爬蟲 — — 以爬取 15 萬筆線上醫療咨詢 QA 為例子](https://reurl.cc/mrom69 )
     2.  [【Day 22】Scrapy 簡介]( https://ithelp.ithome.com.tw/articles/10225716)
     3.   [Scrapy官方網頁](https://docs.scrapy.org/en/latest/topics/settings.html)
6. 其他
    1. [ChatGPT](https://chat.openai.com/) (用來debug)
## Start your project
1. 利用 beautifulsoup
2. 利用 selenium
    1. 你要先在終端機(terminal)或是cmd輸入： pip install selenium
    2. from selenium import webdriver
4. 利用 Scrapy
# 初學可能會遇到的問題
## 問題1(webdriver)：版本問題
>現在網路上的教學很多都告訴你要使用webdriver
>然而有一些程式碼可以繞過這個限制
```oy=
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

options =webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
url=("https://twitter.com/i/flow/login")
driver = webdriver.Chrome(options=options,service=Service(ChromeDriverManager().install()))
driver.get(url)
```
## 問題2(沒解決)
```python=
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

#前置作業，取得網頁並打開
options =webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
url=("https://twitter.com/i/flow/login")
driver = webdriver.Chrome(options=options,service=Service(ChromeDriverManager().install()))
driver.get(url)

#開始輸入帳號密碼
element = WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.NAME, 'text'))
    )   
username=driver.find_element(By.NAME,'text')
username.clear()
username.send_keys("我知道要填帳號")
#上面那些都沒問題
#下面開始找不到
element = WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.CLASS_NAME, 'css-175oi2r r-sdzlij r-1phboty r-rs99b7 r-lrvibr r-ywje51 r-usiww2 r-13qz1uu r-2yi16 r-1qi8awa r-ymttw5 r-1loqt21 r-o7ynqc r-6416eg r-oelmt8 r-1ny4l3l'))
    )  
login=driver.find_elements(By.CLASS_NAME,'css-175oi2r r-sdzlij r-1phboty r-rs99b7 r-lrvibr r-ywje51 r-usiww2 r-13qz1uu r-2yi16 r-1qi8awa r-ymttw5 r-1loqt21 r-o7ynqc r-6416eg r-oelmt8 r-1ny4l3l')
login.click()
```

現在程式碼無法找到正確的路徑，X(twitter)的下一步按鍵的element要怎麼尋找。
這還沒測試，我估計會使用css來解決


## 問題3
```python=
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC 

options =webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
url=("https://www.reddit.com/")
driver = webdriver.Chrome(options=options,service=Service(ChromeDriverManager().install()))
driver.get(url)

element = WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.NAME, 'q'))
    )   
keywordInput = driver.find_element(By.NAME,'q')
keyword ="ukraine russia war"
keywordInput.send_keys(keyword)
keywordInput.send_keys(Keys.RETURN)
```
在上面程式碼中我要將keyword送到搜尋框並按下搜尋
不過程式一直報錯
### 以下是報錯內容：
```
Traceback (most recent call last):
  File "c:\Users\user1\Desktop\python\爬蟲學習\test.py", line 19, in <module>
    keywordInput = driver.find_element(By.CLASS_NAME,'label-container')
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user1\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 742, in find_element
    return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user1\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 348, in execute
    self.error_handler.check_response(response)
  File "C:\Users\user1\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 229, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".label-container"}
  (Session info: chrome=120.0.6099.130); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception
Stacktrace:
        GetHandleVerifier [0x007F6EE3+174339]
        (No symbol) [0x00720A51]
        (No symbol) [0x00436FF6]
        (No symbol) [0x00469876]
        (No symbol) [0x00469C2C]
        (No symbol) [0x0049BD42]
        (No symbol) [0x00487054]
        (No symbol) [0x0049A104]
        (No symbol) [0x00486DA6]
        (No symbol) [0x00461034]
        (No symbol) [0x00461F8D]
        GetHandleVerifier [0x00894B1C+820540]
        sqlite3_dbdata_init [0x009553EE+653550]
        sqlite3_dbdata_init [0x00954E09+652041]
        sqlite3_dbdata_init [0x009497CC+605388]
        sqlite3_dbdata_init [0x00955D9B+656027]
        (No symbol) [0x0072FE6C]
        (No symbol) [0x007283B8]
        (No symbol) [0x007284DD]
        (No symbol) [0x00715818]
        BaseThreadInitThunk [0x768D7BA9+25]
        RtlInitializeExceptionChain [0x771ABD2B+107]
        RtlClearBits [0x771ABCAF+191]
```

# 利用selenium動態爬蟲 
## 下載標題
以下是我目前找到的方式，不過我還是希望可以傳送關鍵字
這樣我就可以用for迴圈送
再得到網頁的element，去執行不同關鍵字搜尋以獲得更多資料分析
```python=
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC 
import time
#啟動webdriver
#啟動網頁
options =webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
url=("https://www.reddit.com/search/?q=ukraine+russia+war&type=link&cId=93c9a042-19c7-412c-9f9a-26a82612a774&iId=6707bc63-2d01-4aca-9f31-91d77c62dc6c&t=month")
driver = webdriver.Chrome(options=options,service=Service(ChromeDriverManager().install()))
driver.get(url)

#等待特定元素初出現
#準備執行取得元素
element = WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.CLASS_NAME, "absolute"))
    )

#控制javascript   
for i in range(10):
    driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")#滾動網頁
    time.sleep(1)#等待網頁刷新

#取得標題元素並列印
titles =driver.find_elements(By.XPATH,'//*[@id[starts-with(., "search-post-title-t3_")]]')
for title in titles:
    print(title.text)
```
上面的程式碼如果要取用的話需要改code
目前正在想辦法存成一個 excel
## 下載Instragram 照片
(改天再寫)

# 進階版爬蟲(scrapy)
## 簡介
><font color=##28gh>以下這張是說明圖片</font>

![20107875dz9S5phFE7](https://hackmd.io/_uploads/BJEzxDduT.png)
圖片來源： https://docs.scrapy.org/en/latest/topics/architecture.html
### 互動解釋
1. Spider
    * 在Scrapy中，爬蟲是定義如何抓取特定網站資料的類。你需要建立一個Spider類，並定義起始的URL以及如何跟隨鏈接，以及如何從網頁中提取數據。
3. Downloader
    * 負責下載網頁並將其返回給Spiders。Scrapy使用Twisted這個異步網絡引擎，這使得同時下載多個頁面變得容易。 
5. Middleware
    * 中間件是一種機制，允許你在發送請求到接收響應之間進行自定義的處理。你可以使用中間件來修改請求、處理響應，甚至將錯誤處理傳遞給Spiders。
7. Item Pipeline
    * 一個Item是爬蟲從網頁中提取的數據項目。Item Pipeline是用於處理和存儲Item的機制。你可以定義多個Pipeline，每個都執行不同的任務，例如驗證數據、清理數據或將數據存儲到數據庫中。
9. Scrapy Engine
    * 引擎是Scrapy的核心部分，它協調整個爬蟲流程。它處理Spiders、Downloader、中間件和Pipeline之間的通信，確保整個流程順利運行。
11. Scheduler
    * 負責接收來自引擎的請求，並將它們排入隊列，以便Downloder下載。
13. Downloader Middlewares
    * 類似於Spider中間件，但它作用於整個下載過程。可以用來修改請求、處理響應，或者對下載的過程進行其他自定義處理。
---
如果一下子無法理解的話，這裡有更好理解的譬喻
1. Spider
    *    想像爬蟲是一位探險家，他的任務是前往一個未知的島嶼（網站），並按照某種特定的路線（起始URL和鏈接跟隨）收集有價值的寶藏（網頁數據）。
2. Downloader

    * 下載器就像是探險家的運輸隊，負責前往島上，將找到的寶藏（網頁）帶回來。它可以同時處理多個運輸任務，以提高效率。
3. Middleware

     *   中間件就像是探險家的助手，可以在探險家離開和回來的過程中進行各種任務，比如檢查他的裝備、給他提供指南，或者在必要時進行一些特殊的處理。
4. Item Pipeline

      * 寶藏回到基地後，有一群工匠（Item Pipeline）負責對寶藏進行處理和儲存。他們可能會對寶藏進行檢查、修復，然後把它們放入倉庫（數據庫）。
5. Scrapy Engine

    * 引擎就像是整個探險隊的隊長，負責協調和管理每個成員的活動。他向爬蟲下達任務，安排運輸隊的行動，並確保整個探險順利進行。
6. Scheduler

    * 排程器就像是探險隊的任務表，它知道哪些地方還沒有被探險，將這些地點的任務分配給爬蟲和下載器。
7. Downloader Middlewares

    * 下載器中間件就像是運輸隊的特殊技能，它可以在運輸的過程中進行一些特殊的處理，比如防禦、加速等。
### scrapy 在終端機的指令
#### start to your first scrapy project
>首先在打開終端機，可以透過win鍵+R 再輸入cmd 或是直接在編譯器裡面找到終端機
>打開終端機以後，輸入：
```python=
scrapy startproject
```
>按下執行後再輸入：
```python=
scrapy genspider spider名稱 目標網站網址
#spider名稱自己取 
#目標網站網址不用全抄，抄主要部份就好
```
