iT邦幫忙

0

想利用python抓取,特定中文字後面的數字!

  • 分享至 

  • xImage

小區域,時間為10月09日22時57,地點為花蓮縣政府南南西方89.5公里(位於花蓮縣卓溪鄉),深度16.8公里,地震規模3.5

小弟目前在學習爬蟲,會利用爬蟲到中央氣象局抓取地震資訊(最新的的資訊)
我想用python,抓取地震規模後面的3.5這個數值

每個抓取的最新地震,字數不會一樣,所以沒辦法用特定的位置來抓取!

想請問有什麼寫法,可以抓取地震規模後面的數字!!
再請各位大大幫幫忙了,非常感謝

froce iT邦大師 1 級 ‧ 2022-10-10 13:51:32 檢舉
正則表示法。
fs910175 iT邦新手 5 級 ‧ 2022-10-14 22:08:44 檢舉
其實蠻建議去買一本基礎書,把基本功能都翻過一次。 之後要用再回頭去翻語法。 我也學習中,加油!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
2
tryit
iT邦研究生 4 級 ‧ 2022-10-10 03:50:14
最佳解答

照你說的話我可能會這樣寫

import re
dataList = ["小區域,時間為10月09日22時57,地點為花蓮縣政府南南西方89.5公里(位於花蓮縣卓溪鄉),深度16.8公里,地震規模3.5",
"小區域,時間為10月09日22時57,地點為花蓮縣政府南南西方89.5公里(位於花蓮縣卓溪鄉),深度16.8公里,地震規模8",
"小區域,時間為10月09日22時57,地點為花蓮縣政府南南西方89.5公里(位於花蓮縣卓溪鄉),深度16.8公里,地震規模8.7"]#你存資料的地方

for i in dataList:
    if "地震規模" in i:
        index = i.index("地震規模")+4#四個字
        square =  [float(num) for num in re.findall(r'-?\d+\.?\d*',i[index:])][0]
        #避免後面還有字或符號
        print(square)

但是,我猜你是直接抓https://www.cwb.gov.tw/V8/C/E/index.html
這網頁的資料,若不是的話沒差再說。
https://ithelp.ithome.com.tw/upload/images/20221010/20108649GD1fwczRwy.png
https://ithelp.ithome.com.tw/upload/images/20221010/20108649lZxdkZmaUA.jpg

你有沒有想過,直接在爬蟲的時候,直接透過抓取欄位,然後分析規則把裡面的東西爬出來就好呢?
就可以少了一次執行程式的功喔

看更多先前的回應...收起先前的回應...

感謝你,關於你上面說的,我有寫過,但是如果以最近地震那邊的原始碼,抓不到我想要的震級、規模(他們用的好像是ajax),所以我才用另一個方式抓,然後遇到現在這個問題,不知道怎麼取地震規模後面的東西,用了你的程式碼解決了這個問題,非常感謝~

tryit iT邦研究生 4 級 ‧ 2022-10-10 15:46:02 檢舉

喔喔原來如此

obarisk iT邦研究生 2 級 ‧ 2022-10-11 15:59:16 檢舉

你都用 re 了,直接把地震規模一起 re 就好了。

tryit iT邦研究生 4 級 ‧ 2022-10-11 17:46:46 檢舉

秀技術有很多秀法,問題是這是要給人看懂的東西。
此外據我所知,該四字後面其實還有符號連結才連結數字,本問題詢問時是沒有的,在這狀況下一個可用的程式碼才是最佳解

1
Retex
iT邦新手 1 級 ‧ 2022-10-10 03:09:26

split('地震規模')[1]

感謝回覆~,雖然這個我不會用??,有詳細一點的寫法嗎!!

oxxo iT邦研究生 1 級 ‧ 2022-10-11 10:54:02 檢舉

參考看看,拆分後變成串列,取出第二個項目
https://steam.oxxostudio.tw/category/python/basic/string.html#a6

好的感謝您

0
iT邦新手 4 級 ‧ 2022-10-11 04:01:19

研究了一下要怎麼用爬蟲處理 ajax,由於 ajax 是使用 js 向伺服器發出請求,然後接收到伺服器的回應,所以如果先找出想要的資料是透過哪個網址回傳的回應,就能讓爬蟲也對該網址送出請求,得到的回應裡面就有所需要的資料了

  1. 用 F12 開啟開發者工具(我用 Firefox),切換到網路頁面,重整頁面
  2. 由於這案例是回傳 html,所以我是把每個請求一個一個點開看回應內容(不看字型跟圖片的請求),確認跟「最近地震」有關的資料是在哪一個請求,最後在MAP_LIST.html?T=2022101102-找到
  3. 對這個請求按右鍵,在右鍵選單中選擇「於主控台以 Fetch 方式使用」,就會自動幫你把標頭跟 fetch 相關的程式碼都產生好
  4. 在主控台把那段程式碼的await fetch前面加上let response=,把伺服器回傳的結果存到response變數中

html 是文字檔,沒辦法用response.json()處理,在 Using the Fetch API:Processing a text file line by line 找到處理文字檔的範例,只要把範例程式中會用到的變數urlOfFile跟函式processLine(Line)先定義好,再複製貼上就能使用run函式,不過不知道為何範例是直接呼叫使用,照理說應該要加上await才對

以上是一步一步用 js 處理得到資料的過程

若用 python,大概長這樣,header 的部分我是從「於主控台以 Fetch 方式使用」產出的headers複製貼上

from bs4 import BeautifulSoup as bs
import requests
url = f'https://www.cwb.gov.tw/V8/C/E/MOD/MAP_LIST.html?T=2022101102'
header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
        "Accept": "*/*",
        "Accept-Language": "zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3",
        "X-Requested-With": "XMLHttpRequest",
        "Sec-Fetch-Dest": "empty",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-origin",
        "Pragma": "no-cache",
        "Cache-Control": "no-cache"
};
response = requests.get(url, headers=header)

soup = bs(response.text, 'html.parser')

後續的取出數字就是像上面解答的一樣,透過正規表示法抽出來
或是像 retex_z 說的那樣

soup.select('a')[0].getText().split('地震規模')[1]

好的,非常感謝,回家我會再嘗試看看的謝謝您

0
oxxo
iT邦研究生 1 級 ‧ 2022-10-11 10:55:52

提供兩個滿常用的方法:

1.使用正則表達式
https://steam.oxxostudio.tw/category/python/library/re.html

2.使用 split 拆分字串
https://steam.oxxostudio.tw/category/python/basic/string.html#a6

我要發表回答

立即登入回答