给定一个起始 URL start
(以及关于允许域等的一些规则),我想生成一个有向图(V,E),其中的节点V
是可从 到达的页面,并且只要页面上有超链接指向,就会有start
一个弧到页面。(u,v)
E
u
v
有没有一种简单的方法来获得这样的图表scrapy
?如果它可以更容易/更好地实现目标,我也会很高兴使用另一个开源工具。
给定一个起始 URL start
(以及关于允许域等的一些规则),我想生成一个有向图(V,E),其中的节点V
是可从 到达的页面,并且只要页面上有超链接指向,就会有start
一个弧到页面。(u,v)
E
u
v
有没有一种简单的方法来获得这样的图表scrapy
?如果它可以更容易/更好地实现目标,我也会很高兴使用另一个开源工具。
我不知道任何工具或贡献可以精确地产生你想要的东西。你必须为此建立一个scrapy spider。我可以在这里解释必要的步骤:
创建一个scrapy项目并生成一个默认的spider
$ scrapy startproject sitegraph
$ cd sitegraph
$ scrapy genspider graphspider mydomain.com
这将创建一个包含 items.py 文件的目录。在此文件中添加以下行
from scrapy.item import Item, Field
class SitegraphItem(Item):
url=Field()
linkedurls=Field()
在 spiders 目录中,您会发现 graphspider.py 将其替换为(当然 mydomain.com 需要替换):
from scrapy.selector import HtmlXPathSelector
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.utils.url import urljoin_rfc
from sitegraph.items import SitegraphItem
class GraphspiderSpider(CrawlSpider):
name = 'graphspider'
allowed_domains = ['mydomain.com']
start_urls = ['http://mydomain/index.html']
rules = (
Rule(SgmlLinkExtractor(allow=r'/'), callback='parse_item', follow=True),
)
def parse_item(self, response):
hxs = HtmlXPathSelector(response)
i = SitegraphItem()
i['url'] = response.url
i['http_status'] = response.status
llinks=[]
for anchor in hxs.select('//a[@href]'):
href=anchor.select('@href').extract()[0]
if not href.lower().startswith("javascript"):
llinks.append(urljoin_rfc(response.url,href))
i['linkedurls'] = llinks
return i
然后编辑 settings.py 文件并添加(相应地更改文件名):
FEED_FORMAT="jsonlines"
FEED_URI="file:///tmp/sitegraph.json"
现在你可以运行:
$ scrapy crawl graphspider
这将生成一个可用于构建图形的 json 文件。
您可以使用 networkx 之类的包来分析它 ot pygraphviz 来绘制它(不推荐用于大型站点)
import json
import pygraphviz as pg
def loadgraph(fname):
G=pg.AGraph(directed=True)
for line in open(fname):
j=json.loads(line)
url=j["url"]
G.add_node(url)
for linked_url in j["linkedurls"]:
G.add_edge(url,linked_url)
return G
if __name__=='__main__':
G=loadgraph("/tmp/sitegraph.json")
G.layout(prog='dot')
G.draw("sitegraph.png")