0

そこで私はFOPEでの検索を自動化する方法に取り組んできました。マイクロソフトは迷惑なことに、収集したデータにアクセスするためのAPIを提供していません。そのため、ログイン、Cookie、ページの廃棄、そしてそのデータを使用して特定のリンクをさらに取得するというすべての癖を備えたWebブラウザーをエミュレートする必要があります。最後のいくつかの部分は取得できるはずですが、MSがFOPEに使用するセットアップは私を困惑させます。私が知っていることと私が持っていることを投稿しますので、他の管理者やコーダーが助けてくれることを願っています。とにかくMSは実際にはユーザーフレンドリーにしたくないように思われるので、ここにある情報は他の管理者がこの問題を解決するのに役立つかもしれません。

https://sts.messaging.microsoft.com/login.asp

<form name="signin" method="post" id="signin" action="">
<span class="normal">Sign in:</span>                 
<fieldset>
    <label for="email">User name:</label>
    <input type="text" id="email" name="email" maxlength="384" value="" /><br />
    <label for="Password">Password:</label>
    <input type="password" id="Password" name="Password" maxlength="256" /><br />
    <input type="submit" id="submit_signin" name="SignIn" value="Sign in" />
</fieldset>
</form>

ログイン後、 https://admin.messaging.microsoft.com/Home.mvc/に移動します(いくつかの自動リダイレクトの後)。ここで、検索ページに移動する[ツール]ボタンをクリックします。

https://admin.messaging.microsoft.com/TraceMessage.mvc/Index/123456

<fieldset>
    <div class="legend">
        <h3><span>Search Parameters</span></h3>
    </div>
    <ul class="fieldset">
        <li class="row large">
            <div class="field"><div class="shell">
    <label for="Sender">* Sender address:</label>
    <span class="input"><span><input type="text" id="Sender" name="Sender" value="" /></span></span>
            </div></div>
            <div class="field last"><div class="shell">
    <label for="Recipient">* Recipient address:</label>
    <span class="input"><span><input type="text" id="Recipient" name="Recipient" value="" /></span></span>
            </div></div>
        </li>
        <li class="row large">
            <div class="field"><div class="shell">
    <label for="Start">* Start date:</label>
    <span class="input"><span><input type="text" id="Start" name="Start" value="10/29/2012 1:19:20 PM"/></span></span>
            </div></div>
            <div class="field last"><div class="shell">
    <label for="End">* End date:</label>
    <span class="input"><span><input type="text" id="End" name="End" value="10/31/2012 1:19:20 PM"/></span></span>
            </div></div>
        </li>
        <li class="row large">
            <div class="field"><div class="shell">
    <label for="Adjust">Time zone:</label>
    <div class="input select">
        <select id="Adjust" name="Adjust">
            <option value="-5"  selected="selected"  >
                UTC-5</option>
        </select>
            </div></div></div>
            <div class="field last"><div class="shell">
    <label for="MessageId">Message ID:</label>
    <span class="input"><span><input type="text" id="MessageId" name="MessageId" value=""/></span></span>
            </div></div>
        </li>
    </ul>
    <br />* Fields marked with the star are required.
</fieldset>
<div>
    <span class="buttons">
        <input type="submit" id="submit" value="Search" />
    </span>
</div>

このページでは、送信者(user@exampleSender.com)と受信者ドメイン(exampleReceiver.com)を挿入する必要があります。いくつかのJSを使用してそれが機能していることを示した後、結果がページに入力されます。

プログラムでログインページに投稿するユーザー名とパスワード、およびC#経由でWebサイトにログインする方法を確認しましたが、どちらの解決策もまったく機能していないようです。そこにいるFOPE管理者が、何が起こっているのか、そしてこれをどのように機能させるのかを理解するのに役立つことを願っています。何か試してみたり、詳細情報を提供したりする必要がある場合は、お知らせください。

アップデート#1

だから私はこれについて少し前進しました。XAML側は特別なものではありません(URL用のスペースのあるテキストボックス、検索を開始するためのボタン、およびWPFWebBrowserだけです。

    private void executeButton_Click(object sender, RoutedEventArgs e)
    {
        DateTime timeNow = DateTime.Now;
        TimeZone zone = TimeZone.CurrentTimeZone;
        TimeSpan offset = zone.GetUtcOffset(DateTime.Now);

        this.wbControl.Navigate("https://admin.messaging.microsoft.com/TraceMessage.mvc/Trace/123456?s=" + Uri.EscapeUriString(this.inputTB.Text) + "&r=example.com&d=" + Uri.EscapeUriString(timeNow.AddDays(-29).ToString()) + "&e=" + Uri.EscapeUriString(timeNow.ToString()) + "&a=" + Uri.EscapeUriString(offset.Hours.ToString()));
   }

    private void wbControl_LoadCompleted_1(object sender, NavigationEventArgs e)
    {
        string email = "AUSERNAME";
        string password = "APASSWORD";

        dynamic doc = this.wbControl.Document;

        doc.GetElementById("email").SetAttribute("value", email);
        doc.GetElementById("Password").SetAttribute("value", password);
        doc.GetElementById("submit_signin").InvokeMember("click");
    }

これは現在、機能のテスト用であるため、特定の側面(ユーザー名とパスワード)がハードコーディングされており、最終的にはそのようにはなりません。この時点で、コードのInvokeMember( "click")部分に関しては行き詰まっています。次のようにエラーが発生するようです。

タイプ'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'の例外が>UnknownModuleで発生しました。しかし、ユーザーコードでは処理されませんでした

追加情報:'System.MarshalByRefObject.InvokeMember(string、> System.Reflection.BindingFlags、System.Reflection.Binder、object []、> System.Reflection.ParameterModifier []、System.Globalization.CultureInfo、string [])'は>保護レベルのためアクセスできません

この例外のハンドラーがある場合、プログラムは安全に続行できます。

だから私はそれを空白のtry/catchでラップしましたが、本質的にはそれでもフォームを送信しません。誰か提案はありますか?

アップデート#2

私はずっとフォームを提出するために答えに座っていたようです。IntelliSenseのヘルプが得られないため、動的を慎重に使用する必要があるもう1つの理由。フォームを送信するために私がしたことは次のとおりです。

doc.GetElementById("submit_signin").Click();

ここで、検索から結果を取得する方法(JavaScriptのみ)に取り組み、フォームの送信後に読み込まれるページの読み込みが完了するタイミングを決定する必要があります。

4

1 に答える 1

0

わかりましたので、多くの戦いの後、解決策が機能しました。誰かがそれを複製/改善する必要がある場合は、.cs コードを投稿します。今のところ、それはかなりうまく機能します:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections;
using HtmlAgilityPack;
using System.Data;

namespace TestApp
{
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void executeButton_Click(object sender, RoutedEventArgs e)
    {
        DateTime timeNow = DateTime.Now;
        TimeZone zone = TimeZone.CurrentTimeZone;
        TimeSpan offset = zone.GetUtcOffset(DateTime.Now);

        string email = "USERNAME";
        string password = "PASSWORD";

        List<string> URLList = new List<string>();

        foreach (string domain in Domains)
        {
            URLList.Add("https://admin.messaging.microsoft.com/TraceMessage.mvc/AsyncMessageList/123456?s=" + Uri.EscapeUriString(this.inputTB.Text) + "&r=" + domain + "&d=" + Uri.EscapeUriString(timeNow.AddDays(-29).ToString()) + "&e=" + Uri.EscapeUriString(timeNow.ToString()) + "&a=" + Uri.EscapeUriString(offset.Hours.ToString()));
        }

        var domainQueue = new Queue<string>(URLList);

        Action navigateQueue = () =>
        {
            if (domainQueue.Count != 0)
            {
                this.wbControl.Navigate(domainQueue.Dequeue());
            }
            else
            {
                MessageBox.Show("Completed");
            }
        };

        this.wbControl.LoadCompleted += (o, e0) =>
        {
            if (this.wbControl.IsLoaded == true)
            {
                dynamic doc = this.wbControl.Document;

                try
                {
                    doc.GetElementById("email").SetAttribute("value", email);
                    doc.GetElementById("Password").SetAttribute("value", password);
                    doc.GetElementById("submit_signin").Click();
                }
                catch
                {
                }

                if (e0.Uri.AbsolutePath.Contains("AsyncMessageList"))
                {
                    List<string> DetailsList = new List<string>();
                    DetailsList.AddRange(ExtractAllAHrefTags(doc));

                    foreach (string href in DetailsList)
                    {
                        domainQueue.Enqueue(href);
                    }
                    navigateQueue();
                }

                if (e0.Uri.AbsolutePath.Contains("Details"))
                {
                    resultsTB.Text += ParseEntries(doc);
                    navigateQueue();
                }

            }
        };

        navigateQueue();
    }

    private string ParseEntries(dynamic inputDoc)
    {
        HtmlAgilityPack.HtmlDocument docHAP = new HtmlAgilityPack.HtmlDocument();
        docHAP.LoadHtml(inputDoc.Body.InnerHtml.ToString());

        string csv = "";

        foreach (HtmlNode emNode in docHAP.DocumentNode.SelectNodes("//em"))
        {
            if (emNode.Attributes["class"] == null)
            {
                csv += "\"" + emNode.InnerText.ToString() + "\",";
            }
        }
        csv = csv.Remove(csv.Length - 1, 1) + "\"" + Environment.NewLine;
        return csv;
    }

    private List<string> ExtractAllAHrefTags(dynamic inputDoc)
    {
        HtmlAgilityPack.HtmlDocument docHAP = new HtmlAgilityPack.HtmlDocument();
        docHAP.LoadHtml(inputDoc.Body.InnerHtml.ToString());

        List<string> hrefTags = new List<string>();
        try
        {
            foreach (HtmlNode link in docHAP.DocumentNode.SelectNodes("//a[@href]"))
            {
                HtmlAttribute att = link.Attributes["href"];
                hrefTags.Add("https://" + this.wbControl.Source.Host.ToString() + System.Web.HttpUtility.HtmlDecode(att.Value));
            }
        }
        catch
        {
        }

        return hrefTags;
    }

    private List<string> Domains
    {
        get
        {
            List<string> currentDomains = new List<string>();
            currentDomains.Add("example.com");
            currentDomains.Add("sub.example.com");
            currentDomains.Add("it.example.com");
            return currentDomains;
        }
    }
}
}
于 2012-12-07T21:49:48.597 に答える