import requests
import csv
from bs4 import BeautifulSoup
url = 'https://pokemonkorea.co.kr/pokedex/'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# 필요한 정보 추출
pokemon_list = []
for tr in soup.select('table.poke_dex_table > tbody > tr'):
row = []
for td in tr.select('td'):
row.append(td.text.strip())
pokemon_list.append(row)
# 추출한 정보 .csv 파일로 저장
with open('pokemon_data.csv', mode='w', newline='', encoding='utf-8-sig') as file:
writer = csv.writer(file)
writer.writerow(['pno', 'pname', 'categorize'])
for pokemon in pokemon_list:
writer.writerow(pokemon)
chat gpt에게 사이트 명을 알려줘도 그 내부까지 들어가서 분석을 해주진 않으므로 내부 코드를 몽땅 수정해야 한다.
내가 원하는 데이터는 가장 상단의
No. 0001 의 숫자,
그리고 포켓몬의 이름,
분류(씨앗포켓몬) 이다.
메이 페이지에서 크롤링 할 수 있는데이터는
넘버, 이름, 타입 정보인데 왜 한번 더 페이지를 클릭해야 들어올 수 있는 분류로 정했냐 하면...!
타입은 하나 이상인 경우가 있어서 해당 경우에 데이터에 어떤식으로 추가해줘야 할지 감이 안잡힘ㅠ
허튼 그런 이유로
메인 페이지에서 넘버와 이름을 가지고 오는 코드,
세부 페이지에서 분류를 가지고 오는 코드로 나눠서 작성했다.
메인 페이지에서 넘버와 이름을 가지고 오는 코드
pokemon_list = []
# https://pokemonkorea.co.kr/pokedex/ 페이지에서 바로 추출할 수 있는 넘버, 이름 정보를 리스트에 추가
for item in soup.select('#pokedexlist li'):
no = item.select('h3 p')[0].text.split('.')[1]
name = item.select('h3')[0].text.split()[1]
pokemon_list.append([no, name])
세부 페이지에서 분류를 가지고 오는 코드
pokemon_list = []
# https://pokemonkorea.co.kr/pokedex/view/[number] 페이지에서 추출해야하는 분류를 리스트에 추가
for view in range(1,len(pokemon_list)+1):
typeview = requests.get(url+'view/'+str(view))
soup_type = BeautifulSoup(typeview.content, 'html.parser')
type_name = soup_type.select_one('.bx-detail div:nth-child(3) p')
print(type_name.text)
pokemon_list[view-1].append(type_name.text)
typeview에서 세부페이지인(https://pokemonkorea.co.kr/pakedex/view/[number]) 정보를 받아와 Bueatifulshop으로 파싱 한 후, 원하는 데이터를 가지고 왔다.
분류가 위치한 곳은 .bx-detail > div > div > p 였는데
타입 정보가 위치한 곳도 .bx-detail > div > div > p로 동일하여 데이터가 계속 '풀'이 들어가는 것이다!
그래서 div:nth-child(3)으로 3번째에 있는 데이터를 넣도록 하였다
지금 보니 여기서 넘버와 이름을 가지고 와서 추가했어도 되는거였는데...
고럼 이렇게 데이터가 들어가진다!
최종코드
import requests
import csv
from bs4 import BeautifulSoup
url = 'https://pokemonkorea.co.kr/pokedex/'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# 필요한 정보 추출
pokemon_list = []
# https://pokemonkorea.co.kr/pokedex/ 페이지에서 바로 추출할 수 있는 넘버, 이름 정보를 리스트에 추가
for item in soup.select('#pokedexlist li'):
no = item.select('h3 p')[0].text.split('.')[1]
name = item.select('h3')[0].text.split()[1]
pokemon_list.append([no, name])
# https://pokemonkorea.co.kr/pokedex/view/[number] 페이지에서 추출해야하는 분류를 리스트에 추가
for view in range(1,len(pokemon_list)+1):
typeview = requests.get(url+'view/'+str(view))
soup_type = BeautifulSoup(typeview.content, 'html.parser')
type_name = soup_type.select_one('.bx-detail div:nth-child(3) p')
print(type_name.text)
pokemon_list[view-1].append(type_name.text)
print(pokemon_list)
# 추출한 정보 .csv 파일로 저장
with open('pokemon_data.csv', mode='w', newline='', encoding='utf-8-sig') as file:
writer = csv.writer(file)
writer.writerow(['pno', 'pname', 'categorize'])
for pno in pokemon_list:
writer.writerow(pno)
최종적으로 엑셀로 출력된 데이터와 수정한 데이터
실제로 엑셀로 출력된 데이터는 왼쪽 데이터지만 중복된 숫자가 있는걸 확인할 수 있다.
sql에 삽입할 때 pno를 primary key로 줄 생각이었기에 이렇게 되면 오류가 생길 것 같아 임의로 id 값을 추가했다...
단순히 VALUES를 반복해서 작성하는 것으로는 sql문이 종료되지 않았다는 오류만 뱉어낼 뿐이다
INSERT ALL
INTO POKEMON_MSTR
VALUES (4, '파이리', '도롱뇽포켓몬')
INTO POKEMON_MSTR
VALUES (5, '리자드', '화염포켓몬')
INTO POKEMON_MSTR
VALUES (6, '리자몽', '화염포켓몬')
SELECT *
FROM DUAL;
다음과 같이 INSERT ALL을 써서 데이터를 넣어주면 데이터를 성공적으로 넣을 수 있다.
main 메소드가 아닌 다른 메서드는 자동로 실행되지 않아서 main 메소드에서 호출해야만 실행된다.
메서드 호출
public class Example01 {
public static void main(String[] args) {
System.out.println("첫번째 메소드");
}
static void second(String text) {
System.out.println("두번째 메소드");
}
}
첫번째 메소드
위의 코드 실행결과는
"첫번째 메소드"
로 main 메서드의 print문만 실행되는데 second 메서드를 실행시키기 위해서는 main메서드에서 호출을 해줘야한다.
public class Example01 {
public static void main(String[] args) {
System.out.println("첫번째 메소드");
second("두번째 메서드")
}
static void second(String text) {
System.out.println(text);
}
}
첫번째 메소드
두번째 메서드
메서드 호출문 작성
메서드 이름(파리미터1, 파라미터2, 파라미터3 ...)
파라미터는 없을 수도 있고, 1개 혹은 여러개 있을 수 있다
return 값을 받는 메서드 호출문
public class Example01 {
public static void main(String[] args) {
int result; // 변수 선언
result = add(3,4);
System.out.println(result);
}
static int add(int a, int b) {
int sum = a + b;
return sum;
}
}
main 메서드에서 3과 4라는 파라미터를 add로 넘기면 add 메서드에서는 파라미터 값을 계산하고 호출한 곳으로 리턴 값을 넘겨준다.