age*_*nis 4 python dom graph beautifulsoup networkx
我想要做的是将一个 HTML 站点 DOM(文档对象模型)表示成一个网络图,然后用这个图做一些统计计算(比如度数、介数、接近度、当然绘图等)。我找不到任何直接执行此操作的库或以前的 SO 帖子。我的想法是使用BeautifulSoup图书馆,然后Networkx图书馆。我尝试编写一些代码循环遍历 HTML 结构的每个元素(使用recursive=True)。但我不知道如何识别每个唯一的标签(你在这里看到,在图中添加第二个h1节点会覆盖第一个节点,对于父节点也是如此,因此该图最终是完全错误的)。
import networkx as nx
import bs4
from bs4 import BeautifulSoup
ex0 = "<html><head><title>Are you lost ?</title></head><body><h1>Lost on the Intenet ?</h1><h1>Don't panic, we will help you</h1><strong><pre> * <----- you are here</pre></strong></body></html>"
soup = BeautifulSoup(ex0)
G=nx.Graph()
for tag in soup.findAll(recursive=True):
G.add_node(tag.name)
G.add_edge(tag.name, tag.findParent().name)
nx.draw(G)
G.nodes
#### NodeView(('html', '[document]', 'head', 'title', 'body', 'h1', 'strong', 'pre'))
Run Code Online (Sandbox Code Playgroud)
关于如何完成的任何想法(包括完全不同的方法)。谢谢
PS:图形可以是有向的,也可以没有,我不在乎。
您可以遍历content每个BeautifulSoup对象的属性。要显示标签,只需使用中的with_labels属性nx.draw:
import networkx as nx
import matplotlib.pyplot as plt
from collections import defaultdict
from bs4 import BeautifulSoup as soup
ex0 = "<html><head><title>Are you lost ?</title></head><body><h1>Lost on the Intenet ?</h1><h1>Don't panic, we will help you</h1><strong><pre> * <----- you are here</pre></strong></body></html>"
d = soup(ex0, 'html.parser')
def _traverse_html(_d:soup, _graph:nx.Graph, _counter, _parent=None) -> None:
for i in _d.contents:
if i.name is not None:
try:
_name_count = _counter.get(i.name)
if _parent is not None:
_graph.add_node(_parent)
_graph.add_edge(_parent, i.name if not _name_count else f'{i.name}_{_name_count}')
_counter[i.name] += 1
_traverse_html(i, _graph, _counter, i.name)
except AttributeError:
pass
_full_graph = nx.Graph()
_traverse_html(d, _full_graph, defaultdict(int))
nx.draw(_full_graph, with_labels = True)
plt.show()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
637 次 |
| 最近记录: |