【问题标题】:Get Links From Web Page [closed]从网页获取链接[关闭]
【发布时间】:2013-09-06 17:05:28
【问题描述】:

我需要将此网页中的所有项目链接(URL)放入一个由中断分隔的文本文件中(换句话说,像这样的列表:“项目#1”“项目#2”等。

http://dota-trade.com/equipment?order=name 是网页,如果您向下滚动,它会继续滚动到大约 500-1000 个项目。

我必须使用什么编程语言或者我将如何做到这一点。我也有使用 imacros 的经验。

【问题讨论】:

  • 应该可以使用 C#、Python 和 Ruby。不过,Javascript 会很棘手。如果您要问,一般有多少种编程语言可以做到这一点,这里就不一一列举了。
  • 您认为最简单的语言是什么?我添加 javascript 的唯一原因是因为我熟悉使用 imacros,并且我可以使用 EVAL 命令在其中获取 javascript。也许有人会知道如何通过 imacros 做到这一点。
  • 从上面提到的三个中,我会推荐Python。或者让我们这样说:您已经学习了哪些编程语言?
  • 我做了一个 Python 初学者教程,但是很短。就是这样。你觉得在 python 中使用 lxml 来做到这一点怎么样?
  • 我对使用 Python 处理 HTML 的了解不够,而且我也不确定在没有任何额外库的情况下是否需要额外的库。合乎逻辑的方法:阅读有关如何使用 Python 访问和编辑 .txt 文件的信息。了解如何使用 Python 访问 Web 内容。查找有关处理 HTML 并将其存储在 .txt 文件中的教程。

标签: c# javascript python ruby imacros


【解决方案1】:

您需要下载 HtmlAgilityPack

using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            WebClient wc = new WebClient();
            var sourceCode = wc.DownloadString("http://dota-trade.com/equipment?order=name");
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(sourceCode);
            var node = doc.DocumentNode;
            var nodes = node.SelectNodes("//a");
            List<string> links = new List<string>();
            foreach (var item in nodes)
            {
                var link = item.Attributes["href"].Value;
                links.Add(link.Contains("http") ? link : "http://dota-trade.com" +link);
            }
            int index = 1;
            while (true)
            {
                sourceCode = wc.DownloadString("http://dota-trade.com/equipment?order=name&offset=" + index.ToString());
                doc = new HtmlDocument();
                doc.LoadHtml(sourceCode);
                node = doc.DocumentNode;
                nodes = node.SelectNodes("//a");
                var cont = node.SelectSingleNode("//tr[@itemtype='http://schema.org/Thing']");
                if (cont == null) break; 
                foreach (var item in nodes)
                {
                    var link = item.Attributes["href"].Value;
                    links.Add(link.Contains("http") ? link : "http://dota-trade.com" + link);
                }
                index++;
            }
            System.IO.File.WriteAllLines(@"C:\Users\Public\WriteLines.txt", links);
        }
    }
}

【讨论】:

  • 这段代码有效。只是为了说明我使用了 Microsoft Visual Studio Ultimate 2012 RTM。我安装了它(花了将近 2 个小时)。我启动了 Visual Studio 2012。我单击“文件”,然后单击“新建项目”,然后在“已安装 -> 模板 -> Visual C# -> Windows -> 控制台应用程序”下,然后按“确定”。应该会出现一个名为 Program.cs 的新页面。将 Kubik 制作的内容粘贴到窗口中,覆盖已经存在的内容。
  • 下载 HtmlAgilityPack。我从htmlagilitypack.codeplex.com 得到我的现在单击“项目”,然后单击“添加引用”。弹出参考管理器后,单击“浏览”,然后单击弹出窗口右下方的“浏览”。导航到您下载的 HtmlAgilityPack 的 Net45 文件夹中的 HtmlAgilityPack.dll。现在按“确定”并按 F5。应该像魅力一样工作。
  • 现在笔记已经完成了。如果您查看dota-trade.com/equipment?order=name 页面并向下滚动,您会看到该页面一直在滚动。因此,您的代码会选择页面可以看到的所有链接,但如果您向下滚动,则不会看到您可以看到的链接。如何制作代码以便拉取整个页面的源代码,包括向下滚动的部分?
  • 代码已编辑,现在连向下滚动的部分都已下载。
  • 你绝对是天赐之物。非常感谢。您应该在这里回答问题:stackoverflow.com/questions/18668141/…,以便搜索的人能够找到它。我还会将该问题标记为已回答,以便您获得积分!
【解决方案2】:

我建议使用任何支持正则表达式的语言。我经常使用 ruby​​,所以我会做这样的事情:

require 'net/http'
require 'uri'

uri = URI.parse("http://dota-trade.com/equipment?order=name")

req = Net::HTTP::Get(uri.path)
http = Net::HTTP.new(uri.host, uri.port)
response = http.request(request)

links = response.body.match(/<a.+?href="(.+?)"/)

这不是我的想法,但 links[0] 应该是一个匹配对象,之后的每个元素都是一个匹配项。

puts links[1..-1].join("\n")

最后一行应该转储您想要的内容,但可能不包括主机。如果您希望包含主机,请执行以下操作:

puts links[1..-1].map{|l| "http://dota-trade.com" + l }.join("\n")

请记住,这是未经测试的。

【讨论】:

    猜你喜欢
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    相关资源
    最近更新 更多