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级信息过多解决方法 >>>>>>>>>>>>>>>>> ...
随机推荐
- H5入门须知
---恢复内容开始--- 首先,让我们来了解一下H5是做什么的,H5全称为“超文本标记语言”.是对网页进行编辑的技术.H5运用Hbulider进行网页编辑.网页可以分为三部分分别是title(主题)u ...
- 戴尔R710服务器安装系统——配置raid
一,内存二,硬盘(分区,数据量大小)三,电源线,网络线四,raid(raid0,raid1,raid5) 从这里开始 1.进入系统时不用管,默认进入即可 2.在读完内存消息之后,开始读取磁盘消息,在出 ...
- C# winform 打开主界面并关闭登录界面
在winform 界面编程中,我们有时候要在主界面打开之前先显示登录界面,当登录界面用户信息校验正确后才打开主界面,而这时登陆界面也完成使命该功成身退了. 目前有两种方法可实现: 方法1. 隐藏登录界 ...
- MySQL 列,可选择的数据类型(通过sql命令查看:`help create table;`)
MySQL 列,可选择的数据类型(通过sql命令查看:help create table;) BIT[(length)] | TINYINT[(length)] [UNSIGNED] [ZEROFIL ...
- <ROS> 机器人描述--URDF和XACRO
文章转自 https://blog.csdn.net/sunbibei/article/details/52297524 特此鸣谢原创作者的辛勤付出 1 URDF 文件 1.1 link和joint ...
- docker stats监控容器资源消耗
在容器的使用过程中,如果能及时的掌握容器使用的系统资源,无论对开发还是运维工作都是非常有益的.幸运的是 docker 自己就提供了这样的命令:docker stats. 默认输出 docker sta ...
- Groovy与Java集成常见的坑
摘要: groovy特性 Groovy是一门基于JVM的动态语言,同时也是一门面向对象的语言,语法上和Java非常相似.它结合了Python.Ruby和Smalltalk的许多强大的特性,Groovy ...
- Zookeeper 在Windows下的安装过程及测试
安装jdk 安装Zookeeper. 在官网http://zookeeper.apache.org/下载zookeeper.我下载的是zookeeper-3.4.6版本. 解压zookeeper-3. ...
- Java虚拟机--------JVM常见参数
JVM 调优常见参数 Java1.7的jvm参数查看一下官方网站. http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java. ...
- Spring MVC Controller异常处理总结
在项目开发过程中,经常遇到服务被攻击的情况,虽然接口在设计过程中有相当多的安全措施,例如cookie校验.风控.访问熔断等相关技术保证服务的安全性,不过感觉还是有必要收集分析一下这些攻击请求者,以备为 ...