---
# System prepended metadata

title: 幼兒園資料爬蟲 (1)
tags: [Python, Crawler, OCR]

---

# 幼兒園資料爬蟲 (1)
###### tags: `Python` `Crawler` `OCR`
https://github.com/mingpepe/kindergarten_crawler

## 序
目標是爬[這個](https://ap.ece.moe.edu.tw/webecems/pubSearch.aspx)。如果趕時間的話我會用 [selenium](https://www.selenium.dev/)，但我不趕。
## Get HTML
本來以為選個地點再搜尋就是 HTTP GET 後面再帶些參數，沒想到並不是。
首先 GET 目標網頁會 [Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#:~:text=The%20Set%2DCookie%20HTTP%20response,sent%20in%20the%20same%20response.)。後面的 HTTP 操作都需要這些 cookie。
![](https://i.imgur.com/hEHqpIc.png)
接著選擇縣市，會 POST ㄧ些資料回去。
![](https://i.imgur.com/mGATcKt.png)

![](https://i.imgur.com/X7cK4oe.png)
然後有些資料回應。
![](https://i.imgur.com/7MC2GWB.png)
這裡遇到三個問題。
1. 送出去的這些 __ 開頭的欄位[是什麼](https://stackoverflow.com/questions/12786199/access-viewstate-eventvalidation-in-c-sharp)? 就是在 HTML 裡放些隱藏欄位，POST 時要帶上這些資訊。
2. 從瀏覽器的 dev tool 解析過的地方看起來，__LASTFOCUS 是有值的，但從 source 看是沒有的。只能說介面還有改善的空間。
3. POST 的回應除了ㄧ些 HTML 外還有ㄧ些更新 view state 值的資訊。

## OCR
雖然沒有實際做過，不過我直覺認為現有的工具辨識下面這種圖應該不是太難。
![](https://i.imgur.com/37yiXgr.png)
沒想到 OpenCV 裡竟然沒有這種 OCR，於是找到了 [pytesseract](https://pypi.org/project/pytesseract/)，就是把 [tesseract](https://github.com/tesseract-ocr/tesseract) 再包一層。
結果效果超級爛，細看了一下發現[前處裡還是要自己做](https://tesseract-ocr.github.io/tessdoc/ImproveQuality.html)。

一開始的想法是轉灰階再 erode 小雜訊就好，但發現 erode 跟 dilation 的效果跟我認知的一直相反，原來是 OpenCV 假設白/黑分別是前景/背景，跟現在要用的正好相反。

好吧，那應該用 dilation 就可以了，不過試了些參數效果都不理想，最後還是決定自己做。總之概念就是 erode 掉小雜訊再二值化，結果長這樣。
![](https://i.imgur.com/iwTxMxI.png)
我覺得應該要可以了，但結果 tesseract 表現依然很差。
目前的設定是```tessedit_char_whitelist=0123456789 --psm 7 -l eng```。待解決。

## 其它小問題
#### HTTP POST 回來的資料是什麼格式?
一些 HTML + 用 | 分隔的一些資料，如果不是通用的格式可以由瀏覽器來更新，那肯定要有對應的程式來處理。最後在 [```ScriptResource.axd```](https://social.msdn.microsoft.com/Forums/en-US/7d2a8894-d5a1-4314-96d3-bba2a8c48be4/what-is-scriptresourceaxd)找到，原來是我大微軟用來實現 AJAX 的東西。似乎是不需要特別理解。
```javascript=
_parseDelta: function(h) {
    var c = h.get_responseData(), d, i, E, F, D, b = 0, e = null, k = [];
    while (b < c.length) {
        d = c.indexOf("|", b);
        if (d === -1) {
            e = this._findText(c, b);
            break
        }
    ...
```
#### 奇怪的 Cookie
```
_pk_id.xxx
_pk.ref.xxx
```
翻了一下發現是在 [matomo.js](https://github.com/matomo-org/matomo/blob/master/js/piwik.js) 裡定義的。用來分析網站的，第一次知道這個東西。順便發現 [Cookie Database](https://cookiedatabase.org/cookie/matomo/_pk_id/) 這個網站。
```javascript=
function getCookieName(baseName) {
    // NOTE: If the cookie name is changed, we must also update the MatomoTracker.php which
    // will attempt to discover first party cookies. eg. See the PHP Client method getVisitorId()
    return configCookieNamePrefix + baseName + '.' + configTrackerSiteId + '.' + domainHash;
}
```