Python 3.x BeautifulSoup-尝试解析网站,但不确定如何解析json脚本?
作为一个有趣的项目,我一直在尝试解析一个网站的一个随机事实的一天。 我决定今天用BeautifulSoup4和urllib3来尝试这一点。然而不幸的是,我不知道如何深入到脚本元素中,而不是我已经得到的 这是我当前的输出水平:Python 3.x BeautifulSoup-尝试解析网站,但不确定如何解析json脚本?,python-3.x,beautifulsoup,Python 3.x,Beautifulsoup,作为一个有趣的项目,我一直在尝试解析一个网站的一个随机事实的一天。 我决定今天用BeautifulSoup4和urllib3来尝试这一点。然而不幸的是,我不知道如何深入到脚本元素中,而不是我已经得到的 这是我当前的输出水平: { "@context": "http://schema.org", "@type": "Article", "headline": "Fact of the Day: 51 Facts Of the Day for 3/19/2019 ←FACTSlides→", "im
{
"@context": "http://schema.org",
"@type": "Article",
"headline": "Fact of the Day: 51 Facts Of the Day for 3/19/2019 ←FACTSlides→",
"image": "https://www.FACTSlides.com/imgs/ishots/8224.png",
"author": "Luke Reiner",
"genre": "facts",
"publisher": {
"@type": "Organization",
"name": "FACTSlides",
"logo": {
"@type": "ImageObject",
"url": "https:\/\/www.factslides.com\/imgs\/logo.png"
}
},
"url": "https://www.factslides.com/s-Fact-Of-The-Day",
"mainEntityOfPage": "https://www.factslides.com/s-Fact-Of-The-Day",
"datePublished": "2019-03-19",
"dateCreated": "2019-03-19",
"dateModified": "2019-03-19",
"description": "Description.",
"articleBody": "Article clutter here."
}
事实本身存储在articleBody
下,没有分隔,我将使用“.”作为分隔符,如果我走到了那一步
这是我目前掌握的代码:
""" Get a random fact. """
import argparse
import json
import urllib3
from bs4 import BeautifulSoup
PARAMETERS = {
"u": ["url", "passes in a url.", "1"],
}
PARSER = argparse.ArgumentParser(
description="Arguments to parse a url."
)
HTTP = urllib3.PoolManager()
def __load_args(parser, cfg_list):
""" Loads the passed arguments. """
for cfg_key in cfg_list:
if len(cfg_list[cfg_key]) > 3:
parser.add_argument(
"-" + cfg_key,
"--" + cfg_list[cfg_key][0],
help=cfg_list[cfg_key][1],
action=cfg_list[cfg_key][2],
nargs=cfg_list[cfg_key][3],
)
else:
parser.add_argument(
"-" + cfg_key,
"--" + cfg_list[cfg_key][0],
default=None,
help=cfg_list[cfg_key][1],
)
def parse_args(parser, section_list=[]):
""" Parses the loaded arguments. """
for section in section_list:
__load_args(parser, section)
return parser.parse_args()
ARGS = parse_args(PARSER, [PARAMETERS])
RESPONSE = HTTP.request('GET', ARGS.url)
SOUP = BeautifulSoup(RESPONSE.data, features="html.parser")
SOUP_SCRIPT = SOUP.find_all("script")
JS_TEXT = SOUP.find('script', type='application/ld+json').text
print(JS_TEXT)
任何帮助都将不胜感激
注意:我正在解析的事实url是。只要您的json是文本/字符串,您就可以使用
json.loads()
来读取:
import json
JS_TEXT = '''{
"@context": "http://schema.org",
"@type": "Article",
"headline": "Fact of the Day: 51 Facts Of the Day for 3/19/2019 ←FACTSlides→",
"image": "https://www.FACTSlides.com/imgs/ishots/8224.png",
"author": "Luke Reiner",
"genre": "facts",
"publisher": {
"@type": "Organization",
"name": "FACTSlides",
"logo": {
"@type": "ImageObject",
"url": "https:\/\/www.factslides.com\/imgs\/logo.png"
}
},
"url": "https://www.factslides.com/s-Fact-Of-The-Day",
"mainEntityOfPage": "https://www.factslides.com/s-Fact-Of-The-Day",
"datePublished": "2019-03-19",
"dateCreated": "2019-03-19",
"dateModified": "2019-03-19",
"description": "Description.",
"articleBody": "Article clutter here."
}'''
jsonObj = json.loads(JS_TEXT)
我在老师的帮助下解决了这个问题 以下是运行代码:
""" Get a random fact. """
import argparse
import random
import json
from bs4 import BeautifulSoup
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
PARAMETERS = {
"u": ["url", "passes in a url.", "1"],
}
PARSER = argparse.ArgumentParser(
description="Arguments to parse a url."
)
HTTP = urllib3.PoolManager()
def __load_args(parser, cfg_list):
""" Loads the passed arguments. """
for cfg_key in cfg_list:
if len(cfg_list[cfg_key]) > 3:
parser.add_argument(
"-" + cfg_key,
"--" + cfg_list[cfg_key][0],
help=cfg_list[cfg_key][1],
action=cfg_list[cfg_key][2],
nargs=cfg_list[cfg_key][3],
)
else:
parser.add_argument(
"-" + cfg_key,
"--" + cfg_list[cfg_key][0],
default=None,
help=cfg_list[cfg_key][1],
)
def parse_args(parser, section_list=[]):
""" Parses the loaded arguments. """
for section in section_list:
__load_args(parser, section)
return parser.parse_args()
ARGS = parse_args(PARSER, [PARAMETERS])
RESPONSE = HTTP.request('GET', ARGS.url)
SOUP = BeautifulSoup(RESPONSE.data, features="html.parser")
SOUP_SCRIPT = SOUP.find_all("script")
JS_TEXT = SOUP.find('script', type='application/ld+json').text
JSON_OBJ = json.loads(JS_TEXT)
LIST_TEST = []
# print(JSON_OBJ['articleBody'])
for item in JSON_OBJ['articleBody'].split('. '):
LIST_TEST.append(item.strip())
print(random.choice(LIST_TEST) + ".")
我想指出的是,我的delimeter并不是最好的,因为有些“事实”可以用两句话来表达。啊,谢谢!这帮助我打开了实际的项目本身。我会继续努力!在脚本标记中找到它很好。这是我大约一个月前才知道的。一旦我了解到这一点,就完全开启了一个全新的网络抓取水平。@chitown88-你能解释一下你的评论吗?当然。有时,当您试图解析动态页面中的数据时,只有在呈现数据之后,才能在标记中找到数据。但是,有时您可以在html源代码的
标记中看到数据是json格式的。因此,如果您可以找到所有脚本标记,并识别包含json格式数据的特定标记,那么您可以提取该文本,并在json.loads()
中读取该文本。它并不总是存在,但在学习这一点之前,我使用Selenium来呈现页面,然后使用bs4做了很多额外的工作,当时我本可以以一个漂亮的json格式获取数据。如果上面的解决方案有帮助,并且是您想要的,请务必接受答案。