如何访问网页中的嵌入式pdf文件

汤姆·祖恩

当我下载包含嵌入式pdf文件的网址时,我可以访问所有页面html,而不能访问pdf文件本身。我已经尝试过HttpWebRequest,WebClient,HtmlAgilityPack,内存流等。不知道什么路径可以工作。就在我附近。任何帮助表示赞赏。

string url = "http://emaps.emapsplus.com/rdl/MadisonCoAl/MadisonCoAl.aspx?showimg=yes&pid=1701013003029000";

byte[] result;
byte[] buffer = new byte[4096];
WebRequest wr = WebRequest.Create(url);
using (WebResponse response = wr.GetResponse())
{
    using (Stream responseStream = response.GetResponseStream())
    {
        using (MemoryStream memoryStream = new MemoryStream())
        {
            int count = 0;
            do
            {
                count = responseStream.Read(buffer, 0, buffer.Length);
                memoryStream.Write(buffer, 0, count);

            } while (count != 0);

            result = memoryStream.ToArray();

            File.WriteAllBytes(@"C:\testpdf.pdf", result);
       }
    }
}
乔手表

这确实很棘手,因为它实际上不是正在下载的pdf文件。如果它是正常的pdf,则您的代码将正常工作。这是一个运行一些javascript的网页,该javascript发回自身以生成pdf。

对于您眼前的问题,我有答案,但是如果您需要对许多文件执行此操作,则可能还有很长的路要走。为了使它正常工作,我在Fiddler中运行了该页面,以获取它要回发的帖子字符串,然后我使用C#来模拟该过程并将结果另存为pdf。

这很有效,但是问题在于,如果没有通过Fiddler获取帖子字符串的手动步骤,则基本上必须创建一个能够理解所有javascript代码并执行它们以查找字符串生成方式的Web浏览器。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string sURL = "http://emaps.emapsplus.com/rdl/MadisonCoAl/MadisonCoAl.aspx?showimg=yes&pid=1701013003029000";
            string sSource = "";

            byte[] buffer = new byte[4096];
            WebRequest wr = WebRequest.Create(sURL);
            using (WebResponse response = wr.GetResponse())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        int count = 0;
                        do
                        {
                            count = responseStream.Read(buffer, 0, buffer.Length);
                            memoryStream.Write(buffer, 0, count);

                        } while (count != 0);

                        sSource = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
                    }
                }
            }

            if (!string.IsNullOrEmpty(sSource))
            {
                const string sQuoteString = "\"";   // If the values are not being found it could be because the markup is being output with single quotes change this variable from "\"" to "'" in that case
                const string sViewStateString = "__VIEWSTATE";
                const string sEventValidationString = "__EVENTVALIDATION";
                const string sValueString = "value=" + sQuoteString;

                Int32 nIndex1 = sSource.IndexOf(sViewStateString);
                Int32 nIndex2 = default(Int32);
                bool bFoundValues = false;
                string sViewState = "";
                string sEventValidation = "";

                // Look for the view state and event validation tags and grab the values
                // Without these values we cannot continue

                if (nIndex1 > -1)
                {
                    nIndex2 = sSource.IndexOf(sValueString, nIndex1);

                    if (nIndex2 > -1)
                    {
                        nIndex1 = sSource.IndexOf(sQuoteString, nIndex2 + sValueString.Length);

                        if (nIndex1 > -1)
                        {
                            sViewState = sSource.Substring(nIndex2 + sValueString.Length, nIndex1 - nIndex2 - sValueString.Length);
                            nIndex1 = sSource.IndexOf(sEventValidationString);

                            if (nIndex1 > -1)
                            {
                                nIndex2 = sSource.IndexOf(sValueString, nIndex1);

                                if (nIndex2 > -1)
                                {
                                    nIndex1 = sSource.IndexOf(sQuoteString, nIndex2 + sValueString.Length);

                                    if (nIndex1 > -1)
                                    {
                                        sEventValidation = sSource.Substring(nIndex2 + sValueString.Length, nIndex1 - nIndex2 - sValueString.Length);
                                        bFoundValues = true;
                                    }
                                }
                            }
                        }
                    }
                }

                if (bFoundValues == true)
                {
                    Int32 nTimeout = 30;
                    HttpWebRequest oRequest = HttpWebRequest.Create(new Uri(sURL).AbsoluteUri) as HttpWebRequest;
                    string sPostData = "__EVENTTARGET=btnPageLoad&__EVENTARGUMENT=&__VIEWSTATE=" + System.Web.HttpUtility.UrlEncode(sViewState) + "&__EVENTVALIDATION=" + System.Web.HttpUtility.UrlEncode(sEventValidation) + "&hdnLoaded=false&ReportViewer1%24ctl03%24ctl00=&ReportViewer1%24ctl03%24ctl01=&ReportViewer1%24ctl11=&ReportViewer1%24ctl12=standards&ReportViewer1%24AsyncWait%24HiddenCancelField=False&ReportViewer1%24ToggleParam%24store=&ReportViewer1%24ToggleParam%24collapse=false&ReportViewer1%24ctl09%24ClientClickedId=&ReportViewer1%24ctl08%24store=&ReportViewer1%24ctl08%24collapse=false&ReportViewer1%24ctl10%24VisibilityState%24ctl00=Error&ReportViewer1%24ctl10%24ScrollPosition=&ReportViewer1%24ctl10%24ReportControl%24ctl02=&ReportViewer1%24ctl10%24ReportControl%24ctl03=&ReportViewer1%24ctl10%24ReportControl%24ctl04=100";
                    byte[] oPostDataBuffer = System.Text.Encoding.ASCII.GetBytes(sPostData);

                    oRequest.UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10; rv:33.0) Gecko/20100101 Firefox/33.0";
                    oRequest.Timeout = nTimeout * 1000;
                    oRequest.Method = "POST";
                    oRequest.ContentType = "application/x-www-form-urlencoded";
                    oRequest.ContentLength = oPostDataBuffer.Length;

                    using (Stream oRequestStream = oRequest.GetRequestStream())
                    {
                        oRequestStream.Write(oPostDataBuffer, 0, oPostDataBuffer.Length);
                        oRequestStream.Close();
                    }

                    HttpWebResponse oResponse = oRequest.GetResponse() as HttpWebResponse;

                    if (oResponse.StatusCode != HttpStatusCode.OK)
                    {
                        // Error

                        MessageBox.Show(oResponse.StatusCode.ToString());
                    }
                    else
                    {
                        // Status is OK

                        byte[] oBuffer = null;
                        byte[] oFile = null;

                        using (BinaryReader reader = new BinaryReader(oResponse.GetResponseStream()))
                        {
                            using (MemoryStream oMemoryStream = new MemoryStream())
                            {

                                oBuffer = reader.ReadBytes(1024);

                                while (oBuffer.Length > 0)
                                {
                                    oMemoryStream.Write(oBuffer, 0, oBuffer.Length);
                                    oBuffer = reader.ReadBytes(1024);
                                }

                                oFile = new byte[Convert.ToInt32(Math.Floor(Convert.ToDouble(oMemoryStream.Length)))];
                                oMemoryStream.Position = 0;
                                oMemoryStream.Read(oFile, 0, oFile.Length);
                            }
                        }

                        using (FileStream oFileStream = new FileStream("C:\\testpdf.pdf", FileMode.Create))
                        {
                            oFileStream.Write(oFile, 0, oFile.Length);
                        }
                    }

                    MessageBox.Show("PDF downloaded to C:\\testpdf.pdf");
                }
                else
                {
                    MessageBox.Show("Cannot find the __VIEWSTATE and/or __EVENTVALIDATION variables.");
                }
            }
            else
            {
                MessageBox.Show("Cannot find source code for original url.");
            }
        }
    }
}

更新:

帖子数据很可能涉及某种会话,并且在测试之前已经超时。因此,这意味着我们必须变得更有创造力。我承认这是一个反复试验的过程,并且此代码确实是针对该URL量身定制的,对于同一网站上的其他pdf而言可能有效,也可能无效。通过将我之前发布的sPostData字符串与我现在通过Fiddler代理运行网站获取的一个新字符串进行比较,我发现发布的许多变量中只有2个发生了变化。这两个变量都可以在html源代码中找到,这些源代码可以从原始C#代码生成。因此,我们要做的只是一个小的字符串操作,并获取这些变量的副本,然后做我发布的原始代码。看?我们正在共同努力!现在,此更新的代码应该每次都能工作,而不会给出500个内部服务器错误消息。

注意:因为我们要发布的数据尚未针对Web进行正确编码,所以我们必须包含对system.web的引用才能访问urlencode方法。为此,您需要:

  1. 右键单击“解决方案资源管理器”中的“参考”,然后选择“添加参考”
  2. 单击左侧的“程序集”,然后在“框架”部分中找到“ System.Web”,或使用最右侧的搜索框
  3. 选中“ System.Web”旁边的复选框,然后单击“确定”

这是简化捕获回发数据的代码

        var postData = new System.Collections.Generic.List<string>();
        var document = new HtmlWeb().Load(url);
        foreach (var input in document.DocumentNode.SelectNodes("//input[@type='hidden']"))
        {
            var name = input.GetAttributeValue("name", "");
            name = Uri.EscapeDataString(name);
            var value = input.GetAttributeValue("value", "");
            value = Uri.EscapeDataString(value);
            if (name == "__EVENTTARGET")
            {
                value = "btnPageLoad";
            }

            postData.Add(string.Format("{0}={1}", name, value));
        }

        // Use StringBuilder for concatenation 
        System.Text.StringBuilder sb = new System.Text.StringBuilder(postData[0]);
        for (int i = 1; i < postData.Count; i++)
        {
            sb.Append("&");
            sb.Append(postData[i]);
        }
        var postBody = sb.ToString();

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何从网页下载嵌入式RTF文件?

使用Java在Excel中读取嵌入式pdf文件

如何使用HTML中的嵌入式Java应用程序进行本地文件系统访问

如何访问POST请求中的嵌入式键值

如何访问Pandas DataFrame中的嵌入式json对象?

如何使用iText检查PDF中的嵌入式字体

下载嵌入式PDF文件

如何访问嵌入式附件?

如何访问嵌入式组件的PropType?

如何使用嵌入式jar文件中可用的功能?

在嵌入式功能中访问功能

访问GoLang中的嵌入式方法

ggplot pdf中的嵌入式字体

在闪亮的应用程序中,当源文件更改时,如何强制和嵌入式pdf查看器刷新

如何为Ionic 3页面中的嵌入式网页清理此URL?

Dotnet CORE 3.1 - 访问关联项目库中的嵌入式资源(文件)

使用PyPDF2检测Google Docs生成的PDF文件中的非嵌入式字体

在Flutter中显示适用于iOS的PDF嵌入式文件

嵌入式 PDF 在 IE 中仅显示文件名,在 chrome 中正常工作

资源文件(.resx)与反射以访问嵌入式资源

无需完全解析即可提取嵌入式PDF文件

使用Python自动下载嵌入式PDF文件

如何在Spring JPA中访问嵌入式类的字段

如何在类型脚本中访问嵌入式输入字段

如何使用Visual C#访问Visual Studios中的嵌入式资源?

如何在C ++中嵌入Chromium嵌入式框架

如何在嵌入式模式下从 Drill 访问 HDFS?

访问嵌入式内存中的HSQLDB实例

访问 hydra:member 中的嵌入式关系的 Api 平台