使用C#读取Firefox书签

7
使用C#,我需要获取所有Firefox书签以将它们导入我们的数据库。我该如何做到这一点?
我知道SO问题Read FF 3 bookmarks in Java,但那里的答案似乎都围绕Java数据库驱动程序展开,并且我不确定其中某些答案是否与Java特定相关。
我的主要问题是,“我该如何在C#中读取Firefox书签?”
次要问题:我看到\%user profile%\application data\mozilla\firefox\profiles\bookmarkbackups\bookmarks-[date].json文件 - 我可以解析它吗?如果可以,是否有任何现有的解析器可用?
反问抱怨:为什么不能像IE一样简单,我只需读取\%user profile%\favorites中的.url文件?Bah.

这并不像IE那样容易,因为Firefox中的书签比IE更复杂,并且Firefox必须是跨平台的。更复杂的要求意味着更复杂的代码。 - Mr. Shiny and New 安宇
3
IE以纯文本格式将它们存储为常规文件。这不是跨平台的吗? - Judah Gabriel Himango
IE的做法至少有一个原因不如FF好。文件名不能包含一些特殊字符,如正斜杠(/)。更不用说FF还支持书签标记了。 - Ionuț G. Stan
2
没错,但这并不是不能通过常规文件解决的问题。只需以纯文本格式或XML格式放置一个[标题]即可。叹气。使用数据库似乎有点过头了。哦,也许我只是太悲观了。 :-) - Judah Gabriel Himango
5个回答

7

使用SQLite驱动程序来访问名为places.sqlite的文件,该文件可以在以下位置找到:
Application Data/Mozilla/Firefox/Profiles/$this_varies/places.sqlite
在我的电脑上。您应该很容易地在目标计算机上找到它。


编辑1:
这是一个打印数据库中URL的代码片段:

using System.Data.SQLite; // downloaded from http://sourceforge.net/projects/adodotnetsqlite

namespace sqlite_test
{
    class Program
    {
        static void Main(string[] args)
        {
            var path_to_db = @"C:\places.sqlite"; // copied here to avoid long path
            SQLiteConnection sqlite_connection = new SQLiteConnection("Data Source=" + path_to_db + ";Version=3;New=True;Compress=True;");

            SQLiteCommand sqlite_command = sqlite_connection.CreateCommand();

            sqlite_connection.Open();

            sqlite_command.CommandText = "select * from moz_places";

            SQLiteDataReader sqlite_datareader = sqlite_command.ExecuteReader();

            while (sqlite_datareader.Read())
            {
                // Prints out the url field from the table:
                System.Console.WriteLine(sqlite_datareader["url"]);
            }
        }
    }
}

编辑2:
小提示:我非常推荐使用Firefox的SQLite Manager插件。它对于处理SQLite数据库非常有用。


谢谢,我已经将其标记为正确答案。看起来备份文件以 .json 格式存储,但仅适用于 FF3 及更高版本。对于阅读此内容的人来说,底线是这样的:
  • FF3 使用 SQLLite 存储书签。它使用 .json 文件来备份书签。
  • FF2 使用 bookmarks.html 文件来存储书签。
- Judah Gabriel Himango
1
值得一提的是,SQLite库的官方网站实际上是http://sqlite.phxsoftware.com——这是一个令人惊叹的产品,非常精致,并且还是公共领域! - Nathan Ridley
1
你提到的SQLite ADO.NET提供程序已经不再维护了,建议使用这个:http://sqlite.phxsoftware.com/。它非常完整,甚至支持实体框架。 - Thomas Levesque
@Nathan:你比我快了一分钟 ;) - Thomas Levesque
您可以使用Visual Studio包管理器安装System.Data.SQLite提供程序:PM> Install-Package System.Data.SQLite - Gordon Bell

2
肯定的,它的工作方式与Java问题中建议的方式相同,只需获取SQLite .NET provider并使用它来访问FF数据库文件。

直接解析 .json 书签备份文件怎么样?这样会更容易吗? - Judah Gabriel Himango

1

我不得不对我的项目http://www.codertakeout.com进行一些重新制定。希望这个修订能够通过网络上的一些建议来澄清一些事情。

using System.Data.SQLite;  // need to install sqlite .net driver

String path_to_db = @"C:\Documents and Settings\Jeff\Application Data\Mozilla\Firefox\Profiles\yhwx4xco.default\places.sqlite";
String path_to_temp = System.IO.Path.GetTempFileName();

System.IO.File.Copy(path_to_db, path_to_temp, true);
SQLiteConnection sqlite_connection = new SQLiteConnection("Data Source=" + path_to_temp + ";Version=3;Compress=True;Read Only=True;");

SQLiteCommand sqlite_command = sqlite_connection.CreateCommand();

sqlite_connection.Open();

sqlite_command.CommandText = "SELECT moz_bookmarks.title,moz_places.url FROM moz_bookmarks LEFT JOIN moz_places WHERE moz_bookmarks.fk = moz_places.id AND moz_bookmarks.title != 'null' AND moz_places.url LIKE '%http%';";

SQLiteDataReader sqlite_datareader = sqlite_command.ExecuteReader();

while (sqlite_datareader.Read())
    {
        System.Console.WriteLine(sqlite_datareader[1]);
    }
sqlite_connection.Close();
System.IO.File.Delete(path_to_temp);

1

访问http://myexps.blogspot.com以获取Java实现。

import java.sql.*;

public class helloWorld {
  public static void main(String[] args) throws Exception {
      Class.forName("org.sqlite.JDBC");
      Connection conn = DriverManager.getConnection("jdbc:sqlite:/home/deepak/.mozilla/firefox/yvf7p20d.default/places.sqlite//");
  if(conn==null)
  {
   System.out.println("ERROR");
  }
  System.out.println(conn.toString());

  Statement stat = conn.createStatement();

  ResultSet rs = stat.executeQuery("select * from moz_bookmarks;");
  while (rs.next()) {
      System.out.println("id = " + rs.getString("id"));
      System.out.println("keyword = " + rs.getString("keyword_id"));
      System.out.println("title = " + rs.getString("title"));
  }
  rs.close();
  conn.close();
  }
}

这将是Java的实现


1

有一个适用于.Net的SQLite驱动程序。一旦你让它工作起来,我想解决方案在.Net和Java中应该是相同的。


直接解析 .json 书签备份文件怎么样?这样会更容易吗? - Judah Gabriel Himango
另外,假设我选择了.NET的SQLLite驱动程序,那么SQLLite数据库文件在哪里? - Judah Gabriel Himango
请查看这篇博客文章,它更详细地解释了FF书签以及它们存储在哪里:http://www.lytebyte.com/2008/06/19/understanding-how-and-where-firefox-3-bookmarks-are-saved/ - Tom van Enckevort

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接