新闻系统(3)内容保护的探索

这些年,互联网垃圾站已经成为一个非常大规模的产业,所谓天下文章一大抄,特别是在版权意识不强的中国,这个现象尤为严重,当一个网站辛苦整理的资料被人疯狂转载的时候,原创的网站可能都会被当成是垃圾网站了。在以往,搜索引擎不是很喜欢论坛和博客的资料,也许以为灌水过多,价值不大,可是现在发现搜索引擎非常青睐博客和论坛这些原创资料。
  我们总是希望搜索引擎多收录我们的资料,以便提高流量,所谓seo,可是反过来,当我们被搜索引擎抓取的时候,也是非常适合那些垃圾站的抓取。这可是有点两难。我们看到很多网站都开始转向偏向于宁可少被百度收录,也要保护自己的版权。
  常见的办法是把内容做成图片,把文字做成图片的软件还是比较多,我们就不赘述了,我们主要讨论下能不能用程序来解决这个问题。
  
  Html要绘制成图片,首先得做html的解析,这个是很有难度的,相当于你得做一个浏览器的内核,那么最简单的办法莫过于直接使用ie的浏览器。
  在net中,我们知道WebBrowser。那么我们就可以依托这个,来做一个抓屏的效果,我们首先让html在一个web地址上呈现,再通过我们的WebBrowser去读取这个页面,然后把内容生成图片。
  代码不多,请看代码。首先声明以下很多代码转自网络,我只做了部分扩展。
  
  
  
  
  using System;
  
  using System.Drawing;
  
  using System.Drawing.Imaging;
  
  using System.Windows.Forms;
  
  using mshtml;
  
  namespace webabc
  
  {
  
  public class HtmlToImage
  
  {
  
  int S_Height;
  
  int S_Width;
  
  int F_Height;
  
  int F_Width;
  
  string MyURL;
  
  
  
  public int ScreenHeight
  
  {
  
  get
  
  {
  
  return S_Height;
  
  }
  
  set
  
  {
  
  S_Height = value;
  
  }
  
  }
  
  
  
  public int ScreenWidth
  
  {
  
  get
  
  {
  
  return S_Width;
  
  }
  
  set
  
  {
  
  S_Width = value;
  
  }
  
  }
  
  
  
  public int ImageHeight
  
  {
  
  get
  
  {
  
  return F_Height;
  
  }
  
  set
  
  {
  
  F_Height = value;
  
  }
  
  }
  
  
  
  public int ImageWidth
  
  {
  
  get
  
  {
  
  return F_Width;
  
  }
  
  set
  
  {
  
  F_Width = value;
  
  }
  
  }
  
  
  
  public string WebSite
  
  {
  
  get
  
  {
  
  return MyURL;
  
  }
  
  set
  
  {
  
  MyURL = value;
  
  }
  
  }
  
  
  
  public HtmlToImage(string WebSite, int ScreenWidth, int ScreenHeight, int ImageWidth, int ImageHeight)
  
  {
  
  this.WebSite = WebSite;
  
  this.ScreenHeight = ScreenHeight;
  
  this.ScreenWidth = ScreenWidth;
  
  this.ImageHeight = ImageHeight;
  
  this.ImageWidth = ImageWidth;
  
  }
  
  
  
  public Bitmap GetBitmap()
  
  {
  
  WebPageBitmap Shot = new WebPageBitmap(this.WebSite, this.ScreenWidth, this.ScreenHeight);
  
  
  
  Shot.GetIt();
  
  Bitmap Pic = Shot.DrawBitmap(this.ImageHeight, this.ImageWidth);
  
  return Pic;
  
  }
  
  }
  
  
  
  public class WebPageBitmap
  
  {
  
  WebBrowser MyBrowser;
  
  string URL;
  
  int Height;
  
  int Width;
  
  
  
  public WebPageBitmap(string url, int width, int height)
  
  {
  
  this.URL = url;
  
  this.Width = width;
  
  this.Height = height;
  
  MyBrowser = new WebBrowser();
  
  //if (System.Web.HttpContext.Current.Cache["dd"] == null)
  
  //{
  
  // System.Web.HttpContext.Current.Cache["dd"]=MyBrowser ;
  
  //}
  
  //else
  
  //{
  
  // MyBrowser = (WebBrowser)System.Web.HttpContext.Current.Cache["dd"];
  
  //}
  
  MyBrowser.ScrollBarsEnabled = false;
  
  MyBrowser.Size = new Size(this.Width, this.Height);
  
  }
  
  
  
  public void GetIt()
  
  {
  
  MyBrowser.Navigate(this.URL);
  
  while (MyBrowser.ReadyState != WebBrowserReadyState.Complete)
  
  {
  
  Application.DoEvents();
  
  }
  
  IHTMLDocument2 doc2 = (IHTMLDocument2)MyBrowser.Document.DomDocument;
  
  IHTMLDocument3 doc3 = (IHTMLDocument3)MyBrowser.Document.DomDocument;
  
  IHTMLElement2 body2 = (IHTMLElement2)doc2.body; //doc2.body;
  
  IHTMLElement2 root2 = (IHTMLElement2)doc3.documentElement;//doc3.documentElement;
  
  
  
  // Determine dimensions for the image; we could add minWidth here
  
  // to ensure that we get closer to the minimal width (the width
  
  // computed might be a few pixels less than what we want).
  
  int __width = Math.Max(body2.scrollWidth, root2.scrollWidth);
  
  int __height = Math.Max(root2.scrollHeight, body2.scrollHeight);
  
  
  
  this.Height = __height;
  
  this.Width = __width;
  
  MyBrowser.Size = new Size(__width, __height);
  
  }
  
  
  
  public Bitmap DrawBitmap(int theight, int twidth)
  
  {
  
  Bitmap myBitmap = new Bitmap(this.Width, this.Height);
  
  Rectangle DrawRect = new Rectangle(0, 0, this.Width, this.Height);
  
  MyBrowser.DrawToBitmap(myBitmap, DrawRect);
  
  System.Drawing.Image imgOutput = myBitmap;
  
  
  
  System.Drawing.Bitmap oThumbNail = new Bitmap(this.Width, this.Height, imgOutput.PixelFormat);
  
  Graphics g = Graphics.FromImage(oThumbNail);
  
  //g.Clear(Color.Transparent);
  
  
  
  
  
  g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
  
  g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  
  g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  
  
  
  Rectangle oRectangle = new Rectangle(0, 0, this.Width, this.Height);
  
  
  
  ImageAttributes attr = new ImageAttributes();
  
  
  
  //attr.SetColorKey(Color.White,Color.White);
  
  
  
  g.DrawImage(imgOutput, oRectangle, 0, 0, imgOutput.Width, imgOutput.Height, GraphicsUnit.Pixel, attr);
  
  
  
  try
  
  {
  
  return oThumbNail;
  
  }
  
  catch
  
  {
  
  return null;
  
  }
  
  finally
  
  {
  
  imgOutput.Dispose();
  
  imgOutput = null;
  
  
  
  MyBrowser.Dispose();
  
  MyBrowser = null;
  
  }
  
  
  
  }
  
  }
  
  }
  
  
  
  一些深刻技术分析的文章在博客园也又不少分析,请搜索下他们的代码。我们要说明的几点是。
  
  
  
  IHTMLDocument2 doc2 = (IHTMLDocument2)MyBrowser.Document.DomDocument;
  
  IHTMLDocument3 doc3 = (IHTMLDocument3)MyBrowser.Document.DomDocument;
  
  IHTMLElement2 body2 = (IHTMLElement2)doc2.body; //doc2.body;
  
  IHTMLElement2 root2 = (IHTMLElement2)doc3.documentElement;//doc3.documentElement;
  
  
  
  // Determine dimensions for the image; we could add minWidth here
  
  // to ensure that we get closer to the minimal width (the width
  
  // computed might be a few pixels less than what we want).
  
  int __width = Math.Max(body2.scrollWidth, root2.scrollWidth);
  
  int __height = Math.Max(root2.scrollHeight, body2.scrollHeight);
  
  
  
  this.Height = __height;
  
  this.Width = __width;
  
  MyBrowser.Size = new Size(__width, __height);
  
  这一部分,我们通过对内容的分析,可以得出文档的高,而不是显示器一屏的高。在这里我们还可以扩展一下,直接插入html让WebBrowser进行绘制,而不用去浏览某个网址。大家可以尝试一下。
  
  web调用的代码如下,要注意这个: newThread.SetApartmentState(ApartmentState.STA);
  
  
  
  
  using System;
  using System.Collections.Generic;
  using System.Drawing.Imaging;
  using System.Web;
  using System.Threading;
  /// <summary>
  ///My_html_to_img 的摘要说明
  /// </summary>
  public class My_html_to_img
  {
  public My_html_to_img()
  {
  //
  //TODO: 在此处添加构造函数逻辑
  //
  }
  public string nid="";
  public string oinfo = "E:";
  public string url = string.Empty;
  public string path = "";
  public string NewsContentToImages()
  {
  
  //dd();
  try
  {
  url = "http://www.21nm.net/NewsContentToImages.aspx?id=" + nid;
  //path = System.Web.HttpContext.Current.Server.MapPath("../uploads/newscontentimages/") + nid + ".gif";
  Thread newThread = new Thread(new ThreadStart(dd));
  newThread.Name = "a88";
  newThread.SetApartmentState(ApartmentState.STA);
  newThread.Start();
  oinfo = "1";
  }
  catch (Exception ex)
  {
  oinfo=ex.ToString();
  }
  return oinfo;
  }
  
  void dd()
  {
  try
  {
  webabc.HtmlToImage thumb = new webabc.HtmlToImage(url, 1024, 768, 320, 240);
  System.Drawing.Bitmap x = thumb.GetBitmap();
  x.Save(path, ImageFormat.Gif);
  //Response.ContentType = "image/gif";
  oinfo += "ok";
  //oinfo += "{ " + System.Web.HttpContext.Current.Server.MapPath("../uploads/newscontentimages") + Request.QueryString["id"] + ".gif";
  
  }
  catch (Exception ex)
  {
  oinfo += ex.ToString();// +url + "{ " + System.Web.HttpContext.Current.Server.MapPath("../uploads/newscontentimages") + Request.QueryString["id"] + ".gif";
  //Response.Write(ex.ToString());
  }
  }
  }
  
  
  另外啰嗦一点就是,千万别在web的多线程中用web的对象,貌似使用后,vs不报错,就给一个类似死循环症状,要纠错很麻烦。
  
  一个实际中使用的地址:http://www.21nm.net/html/c61/267230p1.html
  
  这个程序也有一个毛病,就是由于ie内核的绘制,还是比较消耗资源的,不适合实时生成,最好是在添加新闻的时候一次生成图片。或者在服务器资源消耗不高的时候批量生成。
  
  图片的生成还有一个办法,如果文章中的主要是文字,不会有表格,图片什么的,我们可以直接用绘制图片,这样速度比较快,弊端是程序会比较复杂,工作量比较大,需要解析换行,加粗,什么的,要想显示图片或者表格这些就更难了。但是在做小说网这样内容那个,几乎不可能有图片的还是非常可行的。
  
  另外对于文章内容加密,我想到的一个办法,也尝试过的是,把内容des加密,用flash客户端来解密呈现。理论上应该是没问题,可是实施起来却遇到一个问题,没有现成的as的des解密能和net的通用,主要是补全的模式不一样,得自己写一个双方能通用的算法。这个也是比较费时间的。
  
  如果哪位高手能找到或者写出了以上两种的解决方案,或者有其他更好的解决方案,还请赐教吧。
  
  就文章内容是否值得加密,就不用讨论了,就算不值得,可只要客户需要,我们也得做啊。

posted @ 2010-12-24 22:54  左正  阅读(205)  评论(0编辑  收藏  举报