HTML 코드에서 데이터를 추출하여 JSON 형식으로 변환하는 작업을 수행합니다. 이를 간소화하려면 정규 표현식을 사용하는 대신 더 구조화된 방법을 사용하는 것이 좋습니다.
다음은 Python을 사용하여 같은 작업을 수행하는 방법입니다. Python은 정규 표현식 대신 BeautifulSoup과 같은 라이브러리를 사용하여 HTML 파싱을 더 쉽게 할 수 있습니다.
from bs4 import BeautifulSoup
import re
import json
html = """
여기에 HTML 코드를 입력하세요
"""
soup = BeautifulSoup(html, 'html.parser')
data = []
for row in soup.find_all('tr'): # 'tr' 태그를 포함하는 모든 행을 찾습니다.
columns = row.find_all('td') # 'td' 태그를 포함하는 모든 열을 찾습니다.
if len(columns) == 9:
item = {
"name": columns[0].get_text(),
"close": columns[1].get_text(),
"diff": columns[2].get_text(),
"rate": columns[3].get_text(),
"open": columns[4].get_text(),
"hight": columns[5].get_text(),
"low": columns[6].get_text(),
"date": columns[7].get_text()
}
data.append(item)
json_data = json.dumps(data, ensure_ascii=False, indent=2)
print(json_data)
위 코드는 BeautifulSoup를 사용하여 HTML을 파싱하고, 각 행에서 필요한 데이터를 추출하여 JSON 형식으로 변환합니다. 이 방법은 코드가 더 읽기 쉽고 유지 보수하기 쉽다는 장점이 있습니다. HTML 구조가 변경되어도 더 쉽게 수정할 수 있습니다.
위 Python 코드를 Bash 스크립트로 다시 구현할 수 있습니다. Bash 스크립트로 HTML 파싱을 직접 수행하려면 awk와 sed와 같은 텍스트 처리 도구를 사용해야 합니다. 하지만 Python과 BeautifulSoup과 같은 라이브러리를 사용하는 것보다 번거로울 수 있습니다.
아래는 Bash 스크립트로 작업을 수행하는 방법입니다. 입력 HTML은 data.html
파일로 가정하고, 출력 JSON은 output.json
파일로 저장됩니다.
#!/bin/bash
# HTML 파일을 읽어옵니다.
html=$(<data.html)
# 데이터를 저장할 JSON 배열을 선언합니다.
data=()
# 각 데이터 행을 추출하고 배열에 저장합니다.
while read -r line; do
if [[ $line =~ "<tr>"(.+)"<\/tr>" ]]; then
row=${BASH_REMATCH[1]}
if [[ $row =~ "<td>"([^<]+)"<\/td><td>"([^<]+)"<\/td><td>"([^<]+)"<\/td><td>"([^<]+)"<\/td><td>"([^<]+)"<\/td><td>"([^<]+)"<\/td><td>"([^<]+)"<\/td><td>"([^<]+)"<\/td><td>"([^<]+)"<\/td> ]]; then
name=${BASH_REMATCH[1]}
close=${BASH_REMATCH[2]}
diff=${BASH_REMATCH[3]}
rate=${BASH_REMATCH[4]}
open=${BASH_REMATCH[5]}
high=${BASH_REMATCH[6]}
low=${BASH_REMATCH[7]}
date=${BASH_REMATCH[8]}
item="{\"name\":\"$name\",\"close\":\"$close\",\"diff\":\"$diff\",\"rate\":\"$rate\",\"open\":\"$open\",\"high\":\"$high\",\"low\":\"$low\",\"date\":\"$date\"}"
data+=("$item")
fi
fi
done <<< "$html"
# JSON 배열을 출력 파일에 저장합니다.
json_data="["
json_data+=$(IFS=,; echo "${data[*]}")
json_data+="]"
echo "$json_data" > output.json
위 스크립트는 data.html
파일을 읽어와 각 데이터 행을 추출하고 JSON 형식으로 변환하여 output.json
파일에 저장합니다. 이 스크립트는 정규 표현식을 사용하여 HTML을 파싱하고 데이터를 추출합니다.
sed
및 jq
를 사용하여 Bash 스크립트를 더 간소화하고 최적화할 수 있습니다. 다음은 sed
및 jq
를 사용한 스크립트입니다.
#!/bin/bash
# HTML 파일을 읽어옵니다.
html=$(<data.html)
# 데이터 추출 및 JSON 변환을 위한 sed 명령어를 작성합니다.
sed_expr='s/<tr><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><\/tr>/"{\2":{"name":"\1","close":"\2","diff":"\3","rate":"\4","open":"\5","high":"\6","low":"\7","date":"\8"}},/g'
sed_script="/<tr>/!d; $sed_expr"
json_data=$(echo "$html" | sed -r "$sed_script")
# 마지막 JSON 객체의 쉼표를 제거합니다.
json_data="${json_data%,}"
# JSON 배열 형식으로 출력합니다.
echo "[$json_data]" | jq .
이 스크립트는 sed
를 사용하여 HTML에서 데이터를 추출하고 그 결과를 jq
를 사용하여 JSON으로 파싱합니다. sed
명령어를 사용하여 HTML에서 데이터를 추출하는 방법이 복잡하지만 JSON 변환은 jq
를 사용하여 간단하게 수행합니다. JSON 배열 형식으로 출력됩니다.
/<tr>/!d
는 sed
명령어의 패턴과 제어 명령을 사용하는 부분입니다. 이 부분은 <tr>
태그를 포함하지 않는 행을 삭제하는 역할을 합니다. 설명을 자세히 하면 다음과 같습니다.
/.../
패턴 매칭을 나타냅니다.<tr>
은 찾을 패턴으로,<tr>
문자열을 의미합니다.!
는 부정을 나타내며, 즉 패턴을 찾는 것이 아니라 패턴이 없는 행을 선택합니다.d
는 선택한 행을 삭제하는sed
명령어입니다.
따라서 /<tr>/!d
는 <tr>
태그를 포함하지 않는 행을 모두 삭제하는 명령어입니다. 이렇게 하면 HTML에서 데이터 행만 남게 됩니다.
더 간결한 방법으로 Bash 스크립트를 최적화할 수 있습니다. 아래는 sed
와 jq
를 사용하여 스크립트를 더 간소화한 예제입니다.
#!/bin/bash
# HTML 파일을 읽어옵니다.
html=$(<data.html)
# 데이터 추출 및 JSON 변환을 위한 sed 명령어를 작성합니다.
sed_expr='s/<tr><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><\/tr>/{\2:{"name":"\1","close":"\2","diff":"\3","rate":"\4","open":"\5","high":"\6","low":"\7","date":"\8"}},/g'
json_data=$(echo "$html" | sed -r -e "1s/^/{/" -e "$s/$/}/" -e "$sed_expr" | jq -s .)
echo "$json_data"
이 스크립트는 먼저 HTML 파일을 읽어오고, sed
를 사용하여 데이터를 추출하고 JSON 변환합니다. jq -s .
는 결과 JSON 객체를 배열로 래핑합니다.
기존 스크립트보다 좀 더 간결하게 작성되었으며, 여전히 필요한 작업을 수행합니다. 각 부분을 자세히 설명하겠습니다.
아래 스크립트는 sed
와 jq
를 사용하여 HTML 데이터를 파싱하고 JSON 형식으로 변환하는 작업을 수행합니다.
#!/bin/bash
# HTML 파일을 읽어옵니다.
html=$(<data.html)
먼저 data.html
파일의 내용을 html
변수에 저장합니다.
# 데이터 추출 및 JSON 변환을 위한 sed 명령어를 작성합니다.
sed_expr='s/<tr><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><td>\([^<]\+\)<\/td><\/tr>/{\2:{"name":"\1","close":"\2","diff":"\3","rate":"\4","open":"\5","high":"\6","low":"\7","date":"\8"}},/g'
위 코드 블록은 sed
명령어를 위한 표현식을 정의합니다. 이 표현식은 <tr>
태그를 포함하는 각 데이터 행을 찾아 그 내용을 JSON 형식으로 변환합니다. sed_expr
변수에 저장된 이 표현식은 다음과 같은 역할을 합니다.
<tr>
태그로 시작하고</tr>
태그로 끝나는 각 데이터 행을 찾습니다.- 각 행에서 9개의
<td>
태그를 추출하고 그 안의 내용을 정규 표현식을 사용하여 각각의 필드로 추출합니다. 필드 이름과 값을 사용하여 JSON 형식으로 변환합니다. - 각 데이터 행을 JSON 객체로 감싸고 쉼표로 구분하여 배열 형태로 만듭니다.
json_data=$(echo "$html" | sed -r -e "1s/^/{/" -e "$s/$/}/" -e "$sed_expr" | jq -s .)
위 코드 블록은 다음과 같은 작업을 수행합니다.
sed -r -e "1s/^/{/"
은 HTML의 첫 번째 행을{
로 변경하여 JSON 배열을 시작합니다.$s/$/}/"
은 마지막 행을}
로 변경하여 JSON 배열을 종료합니다.$sed_expr
은 앞에서 정의한sed_expr
변수의 내용을 적용하여 데이터 행을 JSON으로 변환합니다.jq -s .
는 결과 JSON 객체를 배열로 래핑합니다. 이렇게 하면 여러 JSON 객체가 포함된 JSON 배열이 생성됩니다.
마지막으로 json_data
변수에 최종 JSON 데이터가 저장되며, 스크립트는 이 데이터를 출력합니다. 이렇게 하면 HTML 데이터가 파싱되어 JSON 형식으로 변환되어 출력됩니다.
주어진 HTML에서 데이터를 추출하여 JSON 형식으로 만들기 위해 다음과 같은 Bash 스크립트를 사용할 수 있습니다. 이 스크립트는 주어진 HTML에서 각 항목을 추출하고 JSON 배열로 구성합니다.
#!/bin/bash
# HTML 데이터
html=$(cat <<EOF
<a href="#" title="CD91일물">CD91일물</a>
<span class="txt-en">CD91</span>
<span class="txt-num">3.76</span>
<span class="txt-num stock-point hold">0.00</span>
<span class="txt-num hold">0.00%</span>
<span class="txt-num">3.76</span>
<span class="txt-num">3.76</span>
<span class="txt-num">3.76</span>
<span class="txt-date">2023.09.15</span>
<a href="#" title="CP91일물">CP91일물</a>
<span class="txt-en">CP91</span>
<span class="txt-num">4.01</span>
<span class="txt-num stock-point hold">0.00</span>
<span class="txt-num hold">0.00%</span>
<span class="txt-num">4.01</span>
<span class="txt-num">4.01</span>
<span class="txt-num">4.01</span>
<span class="txt-date">2023.09.15</span>
EOF
)
# 데이터 추출 및 JSON 배열 만들기
json_data="["
while [[ "$html" =~ "<a href=\"(.+?)\" title=\"(.+?)\">"(.+?)<\/a>" ]]; do
link="${BASH_REMATCH[1]}"
title="${BASH_REMATCH[2]}"
name="${BASH_REMATCH[3]}"
html="${html#*<\/a>}" # 현재 항목 이후의 HTML 부분을 가져옵니다.
if [[ "$html" =~ "<span class=\"txt-num\">(.+?)<\/span>" ]]; then
num1="${BASH_REMATCH[1]}"
html="${html#*<\/span>}"
fi
if [[ "$html" =~ "<span class=\"txt-num\">(.+?)<\/span>" ]]; then
num2="${BASH_REMATCH[1]}"
html="${html#*<\/span>}"
fi
if [[ "$html" =~ "<span class=\"txt-num\">(.+?)<\/span>" ]]; then
num3="${BASH_REMATCH[1]}"
html="${html#*<\/span>}"
fi
if [[ "$html" =~ "<span class=\"txt-date\">(.+?)<\/span>" ]]; then
date="${BASH_REMATCH[1]}"
fi
item="{\"link\":\"$link\",\"title\":\"$title\",\"name\":\"$name\",\"num1\":\"$num1\",\"num2\":\"$num2\",\"num3\":\"$num3\",\"date\":\"$date\"}"
if [[ "$json_data" == "[" ]]; then
json_data="$json_data$item"
else
json_data="$json_data,$item"
fi
done
json_data="$json_data]"
# 결과 출력
echo "$json_data"
이 스크립트는 주어진 HTML에서 각 항목을 추출하고 JSON 배열로 만듭니다. JSON 배열에는 각 항목에 대한 정보가 포함되며, 필요에 따라 더 많은 항목을 추가하거나 수정할 수 있습니다. 이 예제는 주어진 HTML의 구조에 기반하여 작성되었습니다. HTML의 구조가 변경되면 스크립트를 수정해야 할 수 있습니다.
BASH_REMATCH
는 Bash 스크립트에서 사용할 수 있는 특별한 변수로, 정규 표현식을 사용하여 문자열에서 패턴을 추출한 결과를 저장하는 데 사용됩니다. BASH_REMATCH
배열은 =~
연산자를 사용하여 문자열과 정규 표현식 패턴을 비교할 때 생성되며, 배열의 첫 번째 요소(BASH_REMATCH[0]
)에는 패턴과 일치하는 전체 문자열이 포함되고, 이후의 요소(BASH_REMATCH[1]
, BASH_REMATCH[2]
, ...)에는 패턴의 그룹에 해당하는 부분 문자열이 저장됩니다.
예를 들어, 다음과 같은 문자열에서 숫자를 추출하고자 할 때 BASH_REMATCH
를 사용할 수 있습니다.
string="Hello, my phone number is 123-456-7890."
if [[ $string =~ ([0-9]+)-([0-9]+)-([0-9]+) ]]; then
echo "Full match: ${BASH_REMATCH[0]}"
echo "First group: ${BASH_REMATCH[1]}"
echo "Second group: ${BASH_REMATCH[2]}"
echo "Third group: ${BASH_REMATCH[3]}"
fi
위 예제에서, 정규 표현식 ([0-9]+)-([0-9]+)-([0-9]+)
는 숫자 그룹을 추출하기 위한 패턴입니다. =~
연산자를 사용하여 문자열과 패턴을 비교하면, BASH_REMATCH
배열이 채워지고 각 그룹에 해당하는 값이 배열 요소에 저장됩니다.
BASH_REMATCH
는 문자열에서 패턴을 추출하거나 특정 부분 문자열을 가져와야 할 때 유용합니다.
댓글