2017-12-30 8 views
1

Python에서 BeautifulSoup를 사용하여 "script"태그의 코드에서 "SNG_TITLE"및 "ART_NAME"값을 추출하고 싶습니다.Python에서 BeautifulSoup를 사용하여 스크립트 태그에서 데이터 추출

<script>window.__DZR_APP_STATE__ = {"TAB":{"loved":{"data":[{"SNG_ID":"126884459","PRODUCT_TRACK_ID":"360276641","UPLOAD_ID":0,"SNG_TITLE":"Heathens","ART_ID":"647650","PROVIDER_ID":"3","ART_NAME":"Twenty One Pilots","ARTISTS":[{"ART_ID":"647650","ROLE_ID":"0","ARTISTS_SONGS_ORDER":"1","ART_NAME":"Twenty One Pilots","ART_PICTURE":"259dcf52853363d79753ec301377645d","SMARTRADIO":"1","RANK":"487762","LOCALES":[],"__TYPE__":"artist"}],"ALB_ID":"13371165","ALB_TITLE":"Heathens","TYPE":0,"MD5_ORIGIN":"5cea723b83af1ff0a62d65d334b978d4","VIDEO":false,"DURATION":"195","ALB_PICTURE":"3dfc8c9e406cf1bba8ce0695a44a9b7e","ART_PICTURE":"259dcf52853363d79753ec301377645d","RANK_SNG":"967143","SMARTRADIO":"1","FILESIZE_AAC_64":0,"FILESIZE_MP3_64":"0","FILESIZE_MP3_128":"3135946","FILESIZE_MP3_256":0,"FILESIZE_MP3_320":"7839868","FILESIZE_FLAC":"21777150","FILESIZE":"3135946","GAIN":"-12","MEDIA_VERSION":"4","DISK_NUMBER":"1","TRACK_NUMBER":"1","VERSION":"","EXPLICIT_LYRICS":"0","RIGHTS":{"STREAM_ADS_AVAILABLE":true,"STREAM_ADS":"2000-01-01","STREAM_SUB_AVAILABLE":true,"STREAM_SUB":"2000-01-01"},"ISRC":"USAT21601930","DATE_ADD":1497886149,"HIERARCHICAL_TITLE":"","SNG_CONTRIBUTORS":{"mainartist":["Twenty One Pilots"],"engineer":["Adam Hawkins"],"mixer":["Adam Hawkins"],"masterer":["Chris Gehringer"],"drums":["Josh Dun"],"producer":["Mike Elizondo","Tyler Joseph"],"programmer":["Mike Elizondo","Tyler Joseph"],"vocals":["Tyler Joseph"],"writer":["Tyler Joseph"]},"LYRICS_ID":30553991,"__TYPE__":"song"},{"SNG_ID":"99976952","PRODUCT_TRACK_ID":"171067651","UPLOAD_ID":0,"SNG_TITLE":"Stressed Out","ART_ID":"647650","PROVIDER_ID":"3","ART_NAME":"Twenty One Pilots","ARTISTS":[{"ART_ID":"647650","ROLE_ID":"0","ARTISTS_SONGS_ORDER":"1","ART_NAME":"Twenty One Pilots", ...</script> 

코드의 아이디어는 사용자 이름에서 주어진 페이지에서 볼 수있는 모든 노래와 아티스트 이름을 인쇄하는 것입니다 (전체 스크립트를 붙여 너무 깁니다).

import requests 
from bs4 import BeautifulSoup 

base_url = 'https://www.deezer.com/en/profile/1589856782/loved' 

r = requests.get(base_url) 

soup = BeautifulSoup(r.text, 'html.parser') 

user_name = soup.find(class_='user-name') 
print(user_name.text) 

이렇게하면 사용자 이름이 인쇄됩니다.

for script in soup.find_all('script'): 
    print(script.contents) 

제대로 이해하면 필요한 스크립트는 사전이므로 찾기 만하면됩니다. 문제는 정확히 정확히 "스크립트"를 찾는 방법을 모른다는 것입니다. 고유하게 만드는 속성이나 속성이 없습니다. 그래서 나는 페이지의 모든 스크립트를 찾고 그 내용을 인쇄하는 루프를 시도했지만 더 진행하는 방법을 모르겠습니다.

페이지의 특정 "스크립트"만 어떻게 찾을 수 있습니까? 다른 방법으로 값에 액세스 할 수 있습니까?

+0

"window .__ DZR_APP_STATE__"을 (를) 사용하여 스크립트 요소의 압축을 풀려고합니까?코드에서 – RussellB

+0

카운트 스크립트 - 장소를 변경하지 않고 올바른 색인을 얻기 위해 색인을 사용합니다. 세 번째 스크립트'soup.find_all ('script') [2]' – furas

+0

BTW : 스크립트는 일반적인 문자열이므로 표준 문자열 함수를 사용하여 검사 할 수 있습니다. 예를 들어'script.contents :'' – furas

답변

1

스크립트는 코드의 위치를 ​​변경하지 않으므로 코드를 계산하고 색인을 사용하여 올바른 스크립트를 얻을 수 있습니다.

스크립트는 일반 문자열이므로 표준 문자열 기능도 사용할 수 있습니다. 두 가지 방법으로

if '{"loved"' in script.text: 

코드 - 내가 문자열의 일부만을 표시 [:100]를 사용합니다.

import requests 
from bs4 import BeautifulSoup 

base_url = 'https://www.deezer.com/en/profile/1589856782/loved' 

r = requests.get(base_url) 

soup = BeautifulSoup(r.text, 'html.parser') 

all_scripts = soup.find_all('script') 

print('--- first method ---') 
print(all_scripts[6].text[:100]) 

print('--- second method ---') 
for number, script in enumerate(all_scripts): 
    if '{"loved"' in script.text: 
     print(number, script.text[:100]) 

결과 :

--- first method --- 
window.__DZR_APP_STATE__ = {"TAB":{"loved":{"data":[{"SNG_ID":"126884459","PRODUCT_TRACK_ID":"360276 
--- second method --- 
6 window.__DZR_APP_STATE__ = {"TAB":{"loved":{"data":[{"SNG_ID":"126884459","PRODUCT_TRACK_ID":"360276 

편집 : 당신이 올바른 스크립트가있을 때 당신은 만 JSON 문자열을 얻을 파이썬 사전으로 변환 모듈을 json를 사용하는 슬라이스를 사용할 수 있습니다 데이터를 가져올 수 있습니다.

import requests 
from bs4 import BeautifulSoup 
import json 

base_url = 'https://www.deezer.com/en/profile/1589856782/loved' 

r = requests.get(base_url) 

soup = BeautifulSoup(r.text, 'html.parser') 

all_scripts = soup.find_all('script') 

data = json.loads(all_scripts[6].get_text()[27:]) 

print('key:', data.keys()) 
print('key:', data['TAB'].keys()) 
print('key:', data['DATA'].keys()) 
print('---') 

for item in data['TAB']['loved']['data']: 
    print('ART_NAME:', item['ART_NAME']) 
    print('SNG_TITLE:', item['SNG_TITLE']) 
    print('---') 

결과 : 나의 이해가 정확한지

key: dict_keys(['TAB', 'DATA']) 
key: dict_keys(['loved']) 
key: dict_keys(['USER', 'FOLLOW', 'FOLLOWING', 'HAS_BLOCKED', 'IS_BLOCKED', 'IS_PUBLIC', 'CURATOR', 'IS_PERSONNAL', 'NB_FOLLOWER', 'NB_FOLLOWING']) 
--- 
ART_NAME: Twenty One Pilots 
SNG_TITLE: Heathens 
--- 
ART_NAME: Twenty One Pilots 
SNG_TITLE: Stressed Out 
--- 
ART_NAME: Linkin Park 
SNG_TITLE: Numb 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: Animal I Have Become 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: Painkiller 
--- 
ART_NAME: Slipknot 
SNG_TITLE: Before I Forget 
--- 
ART_NAME: Slipknot 
SNG_TITLE: Duality 
--- 
ART_NAME: Skrillex 
SNG_TITLE: Make It Bun Dem 
--- 
ART_NAME: Skrillex 
SNG_TITLE: Bangarang (feat. Sirah) 
--- 
ART_NAME: Limp Bizkit 
SNG_TITLE: Break Stuff 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: I Hate Everything About You 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: Time of Dying 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: I Am Machine 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: Riot 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: So What 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: Pain 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: Tell Me Why 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: Chalk Outline 
--- 
ART_NAME: Three Days Grace 
SNG_TITLE: Gone Forever 
--- 
ART_NAME: Slipknot 
SNG_TITLE: The Devil In I 
--- 
ART_NAME: Linkin Park 
SNG_TITLE: No More Sorrow 
--- 
ART_NAME: Linkin Park 
SNG_TITLE: Bleed It Out 
--- 
ART_NAME: The Doors 
SNG_TITLE: Roadhouse Blues 
--- 
ART_NAME: The Doors 
SNG_TITLE: Riders On The Storm 
--- 
ART_NAME: The Doors 
SNG_TITLE: Break On Through (To The Other Side) 
--- 
ART_NAME: The Doors 
SNG_TITLE: Alabama Song (Whisky Bar) 
--- 
ART_NAME: The Doors 
SNG_TITLE: People Are Strange 
--- 
ART_NAME: My Chemical Romance 
SNG_TITLE: Welcome to the Black Parade 
--- 
ART_NAME: My Chemical Romance 
SNG_TITLE: Teenagers 
--- 
ART_NAME: My Chemical Romance 
SNG_TITLE: Na Na Na [Na Na Na Na Na Na Na Na Na] 
--- 
ART_NAME: My Chemical Romance 
SNG_TITLE: Famous Last Words 
--- 
ART_NAME: The Doors 
SNG_TITLE: Soul Kitchen 
--- 
ART_NAME: The Black Keys 
SNG_TITLE: Lonely Boy 
--- 
ART_NAME: Katy Perry 
SNG_TITLE: I Kissed a Girl 
--- 
ART_NAME: Katy Perry 
SNG_TITLE: Hot N Cold 
--- 
ART_NAME: Katy Perry 
SNG_TITLE: E.T. 
--- 
ART_NAME: Linkin Park 
SNG_TITLE: Given Up 
--- 
ART_NAME: My Chemical Romance 
SNG_TITLE: Dead! 
--- 
ART_NAME: My Chemical Romance 
SNG_TITLE: Mama 
--- 
ART_NAME: My Chemical Romance 
SNG_TITLE: The Sharpest Lives 
--- 
1

경우, 당신이 그것을에서 "SNG_TITLE"만 스크립트 요소를 원한다.

당신은 re을 사용하여 다음과 같이 관심 분야 만 스크립트 요소를 얻을 수 있습니다 :

import requests 
from bs4 import BeautifulSoup 
import re 

base_url = 'https://www.deezer.com/en/profile/1589856782/loved' 

r = requests.get(base_url) 

soup = BeautifulSoup(r.text, 'html.parser') 

user_name = soup.find(class_='user-name') 
print(user_name.text) 

for script in soup(text=re.compile(r'SNG_TITLE')): 
    print(script.parent) 

편집 :

@furas 대답은을 찾기 위해 json를 사용하여 완벽한 솔루션입니다 'SNG_TITLE'및 'ART_TITLE' 내 대답은 'SNG_TITLE'이 (가)있는 스크립트 만 찾는 데 도움이됩니다. 둘을 결합하여 더 나은 코드를 얻을 수 있습니다.

관련 문제