c#: WebBrowser控制台输出
还是处理视频下载所相关的问题。
有些网站,它的页面代码是由页面加载后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控制台输出的更多相关文章
- js控制台输出console
介绍: js的console你可以在firefox的firedbug或者ie和google的f12调试模式下看到,这些主流浏览器的调试模式的控制可以输出一些信息,你的一些js代码测试可以直接在cons ...
- .Net Core 控制台输出中文乱码
Net Core 控制台输出中文乱码的解决方法: public static void Main(string[] args) { Console.Output ...
- 前端不为人知的一面--前端冷知识集锦 前端已经被玩儿坏了!像console.log()可以向控制台输出图片
前端已经被玩儿坏了!像console.log()可以向控制台输出图片等炫酷的玩意已经不是什么新闻了,像用||操作符给变量赋默认值也是人尽皆知的旧闻了,今天看到Quora上一个帖子,瞬间又GET了好多前 ...
- Canopy测试IPython控制台输出
Canopy测试IPython控制台输出
- Maven 执行Javadoc时控制台输出乱码问题
1.0 Maven 执行Javadoc时控制台输出乱码问题 问题描述 最近项目中使用maven-javadoc-plugin生成javadoc时,myEclipse控制台乱码. 插件配置 问题分析 ...
- Java基础知识强化之网络编程笔记10:TCP之客户端读取文本文件服务器控制台输出
1. TCP之客户端读取文本文件服务器控制台输出 (1)客户端:(发送数据到服务端) package cn.itcast_10; import java.io.BufferedReader; impo ...
- java项目中eclipse控制台输出log4j的信息
最近做的一个hadoop项目中,用MR实现了一个比较复杂的问题,其中的日志信息都是使用的是log4j来处理的.但不知怎么控制台不输出日志信息,只能输出System.out.println()信息,这个 ...
- Java基础知识强化之集合框架笔记36:List练习之键盘录入多个数据在控制台输出最大值
1. 键盘录入多个数据,以0结束,要求在控制台输出这多个数据中的最大值 分析: • 创建键盘录入数据对象 • 键盘录入多个数据,我们不知道多少个,所以用集合存储 • 以0结束,这个简单,只要键盘 ...
- log4j中Spring控制台输出Debug级信息过多解决方法
log4j中Spring控制台输出Debug级信息过多解决方法 >>>>>>>>>>>>>>>>> ...
随机推荐
- hdu5001 Walk 概率DP
I used to think I could be anything, but now I know that I couldn't do anything. So I started travel ...
- Python3之set, frozenset记录
set1 = set([1, 2, 3, 4]) set2 = frozenset([1, 2, 3, 4]) print(set1, set2, sep='|||') set1.add(" ...
- java 实现excel 导出功能
实现功能:java导出excel表 1.jsp代码 <form id="zhanwForm" action="<%=path%>/conferences ...
- bootstrap弹出模态框会给body加padding的解决方法
bootstrap弹出模态框会给body加padding,导致页面缩放的解决方法: 在页面或是css文件里加上($paddingSize为less变量,需要改成像素或是其他单位,如12px,1rem) ...
- kafka原理和实践(五)spring-kafka配置详解
系列目录 kafka原理和实践(一)原理:10分钟入门 kafka原理和实践(二)spring-kafka简单实践 kafka原理和实践(三)spring-kafka生产者源码 kafka原理和实践( ...
- JAVA AES CBC 加密 解密
AES 256 , KEY 的长度为 32字节(32*8=256bit). AES 128 , KEY 的长度为 16字节(16*8=128bit) CBC 模式需要IV, IV的值是固定写死,还是当 ...
- 铁板纹理 铁锈Rust
软件:Substance Designer 2017.1.2 这篇文章记录铁锈的制作方法,铁锈效果见图一 图一:铁锈Rust 铁锈的具体制作过程为: 使用BnW Spots 2(Noise)结点生成噪 ...
- 回滚的意义---JDBC事务回滚探究
JDBC手动事务提交回滚的常见写法一直是rollback写在commit的catch之后: try{ conn.setAutoCommit(false); ps.executeUpdate(); ps ...
- 消息对话框 MessageBoxButtons
消息对话框MessageBox经常用于向用户显示通知信息.例如,在操作过程中遇到错误或程序异常,经常会使用这种方式给用户以提示,它是特殊类型的对话框. 在C#中,MessageBox消息对话框位于Sy ...
- java数据类型关系及关系
java中有常见的基本数据类型和引用数据类型,基本数据类型为四类八种如下 整数型(byte,short,int,long) 浮点型(float,double) 字符型(char) 布尔型(boolea ...