首页 > 解决方案 > 如何从python中的网页中获取链接内的链接?

问题描述

我如何去链接并获取其子链接并再次获取其子子链接?例如,

我想去

"https://stackoverflow.com"

然后提取其链接,例如

['https://stackoverflow.com/questions/ask', 'https://stackoverflow.com/?tab=bounties']

并再次转到该子链接并提取那些子链接链接。

标签: pythonweb-scraping

解决方案


我建议为此使用 Scrapy。使用 Scrapy,您可以创建一个蜘蛛对象,然后由 Scrapy 模块运行。

首先,要获取页面上的所有链接,您可以创建一个 Selector 对象并使用 XPath 查找所有超链接对象:

hxs = scrapy.Selector(response)
urls = hxs.xpath('*//a/@href').extract()

由于 hxs.xpath 返回一个可迭代的路径列表,您可以直接迭代它们而不将它们存储在变量中。此外,找到的每个 URL 都应使用回调参数传递回此函数,允许它递归地查找找到的每个 URL 中的所有链接:

hxs = scrapy.Selector(response)
for url in hxs.xpath('*//a/@href').extract():
    yield scrapy.http.Request(url=url, callback=self.parse)

找到的每个路径可能不包含原始 URL,因此必须进行检查:

    if not ( url.startswith('http://') or url.startswith('https://') ):
        url = "https://stackoverflow.com/" + url

最后,可以将每个 URL 传递给不同的函数进行解析,在这种情况下,它只是打印出来的:

    self.handle(url)

所有这些放在一个完整的 Spider 对象中,如下所示:

import scrapy

class StackSpider(scrapy.Spider):
    name = "stackoverflow.com"
    # limit the scope to stackoverflow
    allowed_domains = ["stackoverflow.com"]
    start_urls = [
        "https://stackoverflow.com/",
    ]

    def parse(self, response):
        hxs = scrapy.Selector(response)
        # extract all links from page
        for url in hxs.xpath('*//a/@href').extract():
            # make it a valid url
            if not ( url.startswith('http://') or url.startswith('https://') ):
                url = "https://stackoverflow.com/" + url
            # process the url
            self.handle(url)
            # recusively parse each url
            yield scrapy.http.Request(url=url, callback=self.parse)

    def handle(self, url):
        print(url)

蜘蛛会像这样运行:

$ scrapy runspider spider.py > urls.txt

另外,请记住,运行此代码将使您因堆栈溢出而受到限制。您可能希望找到不同的测试目标,最好是您自己托管的站点。


推荐阅读