还是处理视频下载所相关的问题。

有些网站,它的页面代码是由页面加载后js动态生成,那么其原始的html便不能用。页面渲染后的代码,是我们需要的

c#中,我用WebBrowser这个控件处理。设置项目类型为控制台程序,加Form承载WebBrowser实现。

记录代码以做备忘:

using System;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32; namespace crpj
{
[ComVisible(true)]
public class Form : System.Windows.Forms.Form
{
protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(false);
} public string GetHtmlCode(string url)
{
using (var wc = new WebClient())
{
wc.Encoding = Encoding.UTF8;
return wc.DownloadString(url);
}
}
} class Program
{
private static Timer tmrGet = new Timer();
private static Timer tmrExit = new Timer();
private static WebBrowser browser = new WebBrowser();
//延时获取?
private static int delay = ;
//js注入脚本
private static string jsCode; //禁止网页跳转声音
const int FEATURE_DISABLE_NAVIGATION_SOUNDS = ;
const int SET_FEATURE_ON_PROCESS = 0x00000002; [DllImport("urlmon.dll")]
[PreserveSig]
[return: MarshalAs(UnmanagedType.Error)]
static extern int CoInternetSetFeatureEnabled(
int FeatureEntry,
[MarshalAs(UnmanagedType.U4)] int dwFlags,
bool fEnable); /// <summary>
/// 应用程序的主入口点。
/// </summary>
/// 参数列表:url delay jscode
[STAThread]
static void Main(string[] args)
{
if (args.Length == )
{
Console.WriteLine("error: You must provide at least one URL.");
return;
} CoInternetSetFeatureEnabled(
FEATURE_DISABLE_NAVIGATION_SOUNDS,
SET_FEATURE_ON_PROCESS,
true);
ChackAndSetBrowserEmulation(); var form = new Form();
form.Controls.Add(browser);
browser.ObjectForScripting = form;
browser.ScriptErrorsSuppressed = true;
browser.DocumentCompleted += browser_DocumentCompleted;
browser.Navigate(args[]); if (args.Length > )
delay = int.Parse(args[]);
if (args.Length > )
jsCode = args[]; //因为页面有时需加载js初始化等操作,延时获取其页面内容
tmrGet.Tick += new EventHandler(tmrGet_Tick);
if (delay > )
tmrGet.Interval = delay; //有些网页不触发complete事件,或者时间很长,此定时器做判断,以60秒为界,自结束
tmrExit.Tick += new EventHandler(tmrExit_Tick);
tmrExit.Interval = ;
tmrExit.Start(); Application.Run(form);
} static void tmrExit_Tick(object sender, EventArgs e)
{
OutputHtml();
} //WebBrowser以IE11版本做页面渲染
static void ChackAndSetBrowserEmulation()
{
try
{
string keyName = @"SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION";
using (var key = Registry.CurrentUser.OpenSubKey(keyName, true))
{
string valueName = Path.GetFileName(Application.ExecutablePath);
if (key.GetValue(valueName) == null)
key.SetValue(valueName, );
}
}
catch
{
}
} static void tmrGet_Tick(object sender, EventArgs e)
{
tmrGet.Stop();
OutputHtml();
} static void OutputHtml()
{
tmrExit.Stop();
//避免韩文等乱码
Console.OutputEncoding = Encoding.UTF8;
//browser.DocumentText取不到执行js之后的body文件
string html = browser.Document.GetElementsByTagName("html")[].OuterHtml;
Console.Write(html);
Application.Exit();
} static void ExecJS(string jsCode)
{
var script = browser.Document.CreateElement("script");
script.SetAttribute("type", "text/javascript");
script.SetAttribute("text", "function _func() {" + jsCode + "}");
browser.Document.Body.AppendChild(script);
browser.Document.InvokeScript("_func");
} static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (browser.ReadyState == WebBrowserReadyState.Complete && e.Url == browser.Url)
{
//是否需要js注入?
if (!string.IsNullOrEmpty(jsCode))
{
ExecJS(jsCode);
System.Threading.Thread.Sleep();
} if (delay == )
OutputHtml();
else
tmrGet.Start();
}
}
}
}
 

如此处理,可能得到所需要的html代码。

其在控制台输出图示效果:

并基于此思路,设计进程输出管理器:

    internal class ProcessOutputMgr
{
private static object syncObj = new Object();
private Process process = new Process();
private StringBuilder allData = new StringBuilder();
private bool exitedCalled = false; public ProcessMgr(string fileName, string args)
{
var startInfo = new ProcessStartInfo(fileName);
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = args;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
            //crpj皆以utf-8输出,避免乱码
            startInfo.StandardOutputEncoding = Encoding.UTF8;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true; process.StartInfo = startInfo;
process.EnableRaisingEvents = true; //一定要有这个才能触发Exited 事件
process.Exited += process_Exited;
process.OutputDataReceived += process_OutputDataReceived;
process.ErrorDataReceived += process_ErrorDataReceived;
} public event DataReceivedEventHandler OutputDataReceived;
public event DataReceivedEventHandler ErrorDataReceived;
public event Action<string> AllDataReceived; public bool Start()
{
bool result = process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
return result;
} public void WaitForExit()
{
process.WaitForExit();
} public bool WaitForExit(int milliseconds)
{
return process.WaitForExit(milliseconds);
} private void process_Exited(object sender, EventArgs e)
{
if (!this.exitedCalled && this.allData.Length != )
{
this.exitedCalled = true;
var handler = AllDataReceived;
if (handler != null)
handler(this.allData.ToString());
}
} private void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
lock (syncObj)
{
var handler = OutputDataReceived;
if (handler != null)
handler(sender, e); if (e.Data != null)
this.allData.AppendLine(e.Data);
else
{
var process = sender as Process;
if (process.HasExited && !this.exitedCalled)
{
this.exitedCalled = true;
if (AllDataReceived != null)
AllDataReceived(this.addData.ToString());
}
}
}
} private void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
lock (syncObj)
{
var handler = ErrorDataReceived;
if (handler != null)
handler(sender, e);
}
}
}

c#: WebBrowser控制台输出的更多相关文章

  1. js控制台输出console

    介绍: js的console你可以在firefox的firedbug或者ie和google的f12调试模式下看到,这些主流浏览器的调试模式的控制可以输出一些信息,你的一些js代码测试可以直接在cons ...

  2. .Net Core 控制台输出中文乱码

    Net Core 控制台输出中文乱码的解决方法: public static void Main(string[] args)         {             Console.Output ...

  3. 前端不为人知的一面--前端冷知识集锦 前端已经被玩儿坏了!像console.log()可以向控制台输出图片

    前端已经被玩儿坏了!像console.log()可以向控制台输出图片等炫酷的玩意已经不是什么新闻了,像用||操作符给变量赋默认值也是人尽皆知的旧闻了,今天看到Quora上一个帖子,瞬间又GET了好多前 ...

  4. Canopy测试IPython控制台输出

    Canopy测试IPython控制台输出

  5. Maven 执行Javadoc时控制台输出乱码问题

    1.0  Maven 执行Javadoc时控制台输出乱码问题 问题描述 最近项目中使用maven-javadoc-plugin生成javadoc时,myEclipse控制台乱码. 插件配置 问题分析 ...

  6. Java基础知识强化之网络编程笔记10:TCP之客户端读取文本文件服务器控制台输出

    1. TCP之客户端读取文本文件服务器控制台输出 (1)客户端:(发送数据到服务端) package cn.itcast_10; import java.io.BufferedReader; impo ...

  7. java项目中eclipse控制台输出log4j的信息

    最近做的一个hadoop项目中,用MR实现了一个比较复杂的问题,其中的日志信息都是使用的是log4j来处理的.但不知怎么控制台不输出日志信息,只能输出System.out.println()信息,这个 ...

  8. Java基础知识强化之集合框架笔记36:List练习之键盘录入多个数据在控制台输出最大值

    1. 键盘录入多个数据,以0结束,要求在控制台输出这多个数据中的最大值 分析: •  创建键盘录入数据对象 •  键盘录入多个数据,我们不知道多少个,所以用集合存储 •  以0结束,这个简单,只要键盘 ...

  9. log4j中Spring控制台输出Debug级信息过多解决方法

    log4j中Spring控制台输出Debug级信息过多解决方法 >>>>>>>>>>>>>>>>> ...

随机推荐

  1. #学习笔记#jsp

    jsp简介 JSP(Java Server Pages)是JavaWeb服务器端的动态资源,它与html页面的作用是相同的,显示数据和获取数据. jsp: 作为请求发起页面,例如显示表单.超链接. : ...

  2. hdu5007 Post Robot AC自动机

    DT is a big fan of digital products. He writes posts about technological products almost everyday in ...

  3. Hibernate主键自增策略

    hibernate 主键生成策略配置: 通过 实体类映射文件中 <id>元素的 子元素 <generator> 元素进行配置 <generator> 常用配置: ( ...

  4. php最常见最经典的算法题

    1.一群猴子排成一圈,按1,2,…,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫 ...

  5. 如何在hanlp词典中手动添加未登录词

     我们在使用hanlp词典进行分词的时候,难免会出现分词不准确的情况,原因是由于内置词典中并没有收录当前的这个词,也就是我们所说的未登录词,只要把这个词加入到内置词典中就可以解决类似问题,如何操作,下 ...

  6. 【OpenStack】network相关知识学习

    network 类型 local:通信不跨主机,必须同一网段,主要做单机测试使用: flat:统计可以跨主机,但是需要在同一网段: 每个 flat network 都会独占一个物理网卡 计算节点上 b ...

  7. logback不输出日志消息,且SLF4J绑定源错误

    我之前的项目已经成功使用过logback作为日志输出,但是今天新项目在使用的时候,不输出日志信息. 最后终于找到问题所在,并成功解决.解决步骤如下: 第一步:检查pom.xml 按照以往惯例,我先检查 ...

  8. solr schema.xml Field属性详解

    <field name="id" type="string" indexed="true" stored="true&quo ...

  9. element-ui input输入框回车事件

    <el-input maxlength="30" v-model="answerInput" @keyup.enter.native="addA ...

  10. springboot学习目录

    1.spring boot 简单示例 一个简单的springboot 例子  https://www.cnblogs.com/shoshana-kong/p/9641696.html 2. sprin ...