如何使用 Beautiful Soup 从网站上抓取 SVG 元素?
How to scrape SVG element from a website using Beautiful Soup?
from bs4 import BeautifulSoup
import requests
import random
id_url = "https://codeforces.com/profile/akash77"
id_headers = {
"User-Agent": 'Mozilla/5.0(Windows NT 6.1Win64x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 87.0 .4280 .141 Safari / 537.36 '}
id_page = requests.get(id_url, headers=id_headers)
id_soup = BeautifulSoup(id_page.content, 'html.parser')
id_soup = id_soup.find('svg')
print(id_soup)
我得到 None
作为输出。
如果我解析包含此 <svg>
标记的 <div>
元素,则不会打印 <div>
元素的内容。 find()
适用于除 SVG 标签之外的所有 HTML 标签。
svg标签不包含在源代码中,由Javascript渲染。
该网页是使用 Javascript 动态呈现的,因此您需要 selenium 才能获得呈现的页面。
首先,安装库
pip install selenium
pip install webdriver-manager
然后,您可以使用它来访问整个页面
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
s=Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=s)
driver.maximize_window()
driver.get('https://codeforces.com/profile/akash77')
elements = driver.find_elements(By.XPATH, '//*[@id="userActivityGraph"]')
Elements 是一个 selenium WebElement,因此我们需要从中获取 HTML。
svg = [WebElement.get_attribute('innerHTML') for WebElement in elements]
这会为您提供 svg 和其中的所有元素。
有时,您需要 运行 无头模式浏览器(无需打开 chrome UI),为此您可以将 'headless' 选项传递给driver.
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('headless')
# then pass options to the driver
driver = webdriver.Chrome(service=s, options=options)
如果您只想要 html 中的数据,这不是很好,但它比浏览器自动化更快、更容易:
import requests
import json
url = 'https://codeforces.com/profile/akash77'
resp = requests.get(url)
start = "$('#userActivityGraph').empty().calendar_yearview_blocks("
end = "start_monday: false"
s = resp.text
svg_data = s[s.find(start)+len(start):s.rfind(end)].strip()[:-1].replace('items','"items"').replace('data','"data"').replace('\n','').replace('\t','').replace(' ','') #get the token out the html
broken = svg_data+'}'
json_data = json.loads(broken)
print(json_data)
from bs4 import BeautifulSoup
import requests
import random
id_url = "https://codeforces.com/profile/akash77"
id_headers = {
"User-Agent": 'Mozilla/5.0(Windows NT 6.1Win64x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 87.0 .4280 .141 Safari / 537.36 '}
id_page = requests.get(id_url, headers=id_headers)
id_soup = BeautifulSoup(id_page.content, 'html.parser')
id_soup = id_soup.find('svg')
print(id_soup)
我得到 None
作为输出。
如果我解析包含此 <svg>
标记的 <div>
元素,则不会打印 <div>
元素的内容。 find()
适用于除 SVG 标签之外的所有 HTML 标签。
svg标签不包含在源代码中,由Javascript渲染。
该网页是使用 Javascript 动态呈现的,因此您需要 selenium 才能获得呈现的页面。
首先,安装库
pip install selenium
pip install webdriver-manager
然后,您可以使用它来访问整个页面
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
s=Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=s)
driver.maximize_window()
driver.get('https://codeforces.com/profile/akash77')
elements = driver.find_elements(By.XPATH, '//*[@id="userActivityGraph"]')
Elements 是一个 selenium WebElement,因此我们需要从中获取 HTML。
svg = [WebElement.get_attribute('innerHTML') for WebElement in elements]
这会为您提供 svg 和其中的所有元素。
有时,您需要 运行 无头模式浏览器(无需打开 chrome UI),为此您可以将 'headless' 选项传递给driver.
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('headless')
# then pass options to the driver
driver = webdriver.Chrome(service=s, options=options)
如果您只想要 html 中的数据,这不是很好,但它比浏览器自动化更快、更容易:
import requests
import json
url = 'https://codeforces.com/profile/akash77'
resp = requests.get(url)
start = "$('#userActivityGraph').empty().calendar_yearview_blocks("
end = "start_monday: false"
s = resp.text
svg_data = s[s.find(start)+len(start):s.rfind(end)].strip()[:-1].replace('items','"items"').replace('data','"data"').replace('\n','').replace('\t','').replace(' ','') #get the token out the html
broken = svg_data+'}'
json_data = json.loads(broken)
print(json_data)