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级信息过多解决方法 >>>>>>>>>>>>>>>>> ...
随机推荐
- PythonStudy——python中如何使输出不换行
1.在python 3.x版本中,使用print(,end="") 可使输出不换行, 例如:
- websocket 11
1. websocket 回顾: - 什么是轮训? - 通过定时器让程序每隔n秒执行一次操作. - 什么是长轮训? - 浏览器向后端发起请求,后端会将请求 hang 住,最多hang 30s. 如果一 ...
- zabbix 与 nginx (五)
zabbix监控nginx的大概流程为: 1:被监控端的nginx开启stub_status模块 2:通过脚本的方式获取nginx的状态值 3:修改被监控端的配置文件,Userparameter= ...
- 关于Java流
- day2模块初识别
sys_mod.py import sys print(sys.argv) #['C:/Users/Administrator/desktop/s17/day2/sys_mod.py'] 打印脚本的绝 ...
- Linux下安装MySQL----来自简书(挺好的)
来自简书的: https://www.jianshu.com/p/f4a98a905011 注: 1. 下载方式: 可以使用命令下载: wget http://downloads.mysql.com/ ...
- [UE4]Circular Throbber,圆形的、环形的动态图标
一.就是圆形的,转动的很多小圆点. 二.Circular Throbber.Appearance.Number Of Pieces:可以通知显示的小圆点个数. 三.Circular Throbber. ...
- ps-如何去背景色(将背景色变透明)
由于生活或工作的需求,图片的处理是必不可少.其中将图片某一部分变为透明,或者截取图片的某一部分比较常见. 1.首先,打开待处理的图片: 2.复制背景图层,将背景图层设为不可见(左边的眼睛即可),选择左 ...
- Letsencrypt SSL免费证书申请(Docker)
最近需要SSL证书,又不想花钱买,正好看到linux基金会去年底上线了新的开源项目,免费推广SSL遂尝试. Let's Encrypt 介绍 Let’s Encrypt is a free, auto ...
- SQLServer数据库镜像配置
目录 一.目标...2 二.前提条件.限制和建议...2 三.设置概述...2 四.安装Sql Server 2008 enterprise X64.3 4.1.安装.NET3.5.3 4.2.安装时 ...