myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE
   » Gadget für Windows
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin

Ressourcen
» guide to C#
» openbook: Visual C#
» openbook: OO
» MSDN Webcasts
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Web-Technologien » Automatisierter Download von PDF-Dateien aus indirekter URL
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Automatisierter Download von PDF-Dateien aus indirekter URL

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Arakiss
myCSharp.de-Mitglied

Dabei seit: 26.06.2011
Beiträge: 5


Arakiss ist offline

Automatisierter Download von PDF-Dateien aus indirekter URL

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo liebe myCSharp-Gemeinde,

Oft habt ihr mir schon geholfen mit Themen, die bereits behandelt wurden. Dieses Mal konnte ich leider nichts passendes finden und habe mich kurzerhand registriert. Ich hoffe, ich habe keine Ergebnisse übersehen, aber ich suche seit 2 Stunden in google und bei euch und konnte keine funktionierende Lösung finden. Ferner hoffe ich, dass dies der passende Forumsbereich ist.

Ich muss PDF-Dateien herunterladen aus einem gegebenen Link. Dieser Link funktioniert, wenn ich ihn in den Browser eingebe, aber es ist halt kein direkter Link auf die PDF-Datei. Das PDF wird nur im Browser dargestellt.
Der Link sieht zum Beispiel so aus:
 http://doc.morningstar.com/LatestDoc.asp...0000001W6&dt=52

Natürlich kann ich den Link mit folgendem Code runterladen:

C#-Code:
WebClient webClient = new WebClient();
webClient.DownloadFile(@"http://doc.morningstar.com/LatestDoc.aspx?clientid=on-demand&key=a20d5eed49c96564&language=0L00000122&sid=F0000001W6&dt=52", @"c:\myfile.pdf");

Dabei kommt allerdings nur eine unbrauchbare PDF-Datei raus. In Wirklichkeit lädt er das HTML der Seite runter. Zum Beispiel:

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
<html>
  <head>
    <title>Morningstar Document Library</title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name=vs_defaultClientScript content="JavaScript">
    <meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
  </head>
    <frameset rows="30,*">
		<frame name="DocHead" src="docheader.aspx?id=F0000001W6&type=1&dt=52&market=&language=0L00000122&format=&fl=False" frameBorder="no"
			id="DocHead" scrolling="no">
		<frame name="DocDetail" frameBorder="no" id="DocDetail">
			
		</frame>
	</frameset>
</html>

Jetzt ist meine Frage, wie ich denn an die PDF-Datei zum Download ran komme. Also im Endeffekt müsste das Programm die URL irgendwie aufrufen und dann das PDF aus dem Frame heraus finden und herunterladen.

Für eure Hilfe wäre ich sehr dankbar.

Gruß,

Arakis

*Edit: Was ich noch vergas: Der Frame scheint nach dem Laden über javascript modifiziert zu werden. Im Firefox sieht der HTML-Code (Der wenn man F12 drückt, nicht der Quellcode) des Frames so aus:

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
<frame id="DocDetail" frameborder="no" name="DocDetail">
<html>
<head>
<title>original (application/pdf-Objekt)</title>
</head>
<body marginwidth="0" marginheight="0"><embed width="100%" height="100%" name="plugin" src="http://doc.morningstar.com/Document/8dfc036c3f4e486e968a1f3cc026dd2c.msdoc/original?track=0" type="application/pdf">
</body>
</html>
</frame>

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Arakiss am 26.06.2011 12:00.

26.06.2011 11:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
trashkid2000 trashkid2000 ist männlich
myCSharp.de-Mitglied

Dabei seit: 27.12.2010
Beiträge: 153


trashkid2000 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,
keine Ahnung, ob es rechtlich korrekt ist, die PDF dort automatisiert runterzuladen.
Aber Du scheinst ja einen Zugang zu haben.
Habe mal etwas mit der Seite rumgespielt.
Also, bei dem Aufruf des Links, den Du gepostet hast, wird zum Client ein Cookie übertragen, in dem ein.ASPXAUTH-Wert drin steht. Dieses Cookie wird benötigt, um die Seite, dessen Link im frameset hinterlegt ist (also die docheader.aspx) aufzurufen. Ist das Cookie nicht vorhanden, so wird man automatisch auf die Startseite weitergeleitet.
Der Inhalt der docheader.aspx sieht dann so aus (gekürzt):

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
	Morningstar Document Library
.
.
.
<script type="text/javascript">
    function Init()
    {     
      parent.frames["DocDetail"].location="Document/30940840d5de0dcff1ac26ab028db07a.msdoc?track=0";
     }
</script>
</html>

Wie man sieht, ist in der Init()-Funktion, die automatisch aufgerufen wird, der direkte Link zu der PDF enthalten. Also in diesem Fall
 http://doc.morningstar.com/Document/3094...a.msdoc?track=0
Der Code sieht also folgendermaßen aus:

C#-Code:
Cookie authCookie = null;
string docHeaderUrl = null;
string key = "Dein Key";

Uri baseUri = new Uri("http://doc.morningstar.com");
Uri cookieRequestUri = new Uri(baseUri, string.Format("LatestDoc.aspx?clientid=on-demand&key={0}&language=0L00000122&sid=F0000001W6&dt=52", key));
HttpWebRequest cookieRequest = (HttpWebRequest)WebRequest.Create(cookieRequestUri);
cookieRequest.CookieContainer = new CookieContainer();
using (HttpWebResponse cookieResponse = (HttpWebResponse)cookieRequest.GetResponse())
{
   using (StreamReader cookieResponseReader = new StreamReader(cookieResponse.GetResponseStream()))
   {
      string content = cookieResponseReader.ReadToEnd();
      Regex regex = new Regex("<frame name=\"DocHead\" src=\"(?<url>.+?)\"");
      if (regex.IsMatch(content))
         docHeaderUrl = regex.Match(content).Groups["url"].Value;
   }
   authCookie = cookieResponse.Cookies.OfType<Cookie>().FirstOrDefault(c => c.Name == ".ASPXAUTH");
}
if (string.IsNullOrEmpty(docHeaderUrl))
   throw new InvalidOperationException("no docHeaderUrl was found");
if (authCookie == null)
   throw new InvalidOperationException("no cookie was received");

HttpWebRequest mainRequest = (HttpWebRequest)WebRequest.Create(new Uri(baseUri, docHeaderUrl));
mainRequest.CookieContainer = new CookieContainer();
mainRequest.CookieContainer.Add(authCookie);
mainRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

string documentUri = null;
using (HttpWebResponse mainRequestResponse = (HttpWebResponse)mainRequest.GetResponse())
{
   using (StreamReader mainRequestResponseReader = new StreamReader(mainRequestResponse.GetResponseStream()))
   {
      string content = mainRequestResponseReader.ReadToEnd();
      Regex regex = new Regex("parent\\.frames\\[\"DocDetail\"\\]\\.location=\"(?<url>.+?)\"");
      if (regex.IsMatch(content))
         documentUri = regex.Match(content).Groups["url"].Value;
   }
}
if (string.IsNullOrEmpty(documentUri))
   throw new InvalidOperationException("no documentUrl was found");

Konnte den Code nicht wirklich gut testen, da mein PC mit dem blöden Proxy (Fiddler) spinnt. Visual Studio hat sich immer richtig aufgehangen. Aber hoffe, es klappt so.

//edit: Code verbessert:
- docHeader-Url wird automatisch ausgelesen
- download-Url wird automatisch ausgelesen
- Fehlerbehandlung
- Key ausgekapselt (sollte nicht für jeden sichtbar sein!)
LG, Marko

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von trashkid2000 am 26.06.2011 19:26.

26.06.2011 15:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Arakiss
myCSharp.de-Mitglied

Dabei seit: 26.06.2011
Beiträge: 5

Themenstarter Thema begonnen von Arakiss

Arakiss ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Vielen danke trashkid,
Sieht schon mal sehr gut aus und ich werde es später gleich ausführlich testen. Rechtlich gesehen, darf das nicht jeder bei denen, aber die Firma, für die ich tätig bin und das mache, hat einen gültigen Vertrag. Insofern ist das legal und abgesprochen.

Ich werde später oder morgen noch eine Rückmeldung geben.

Grüße,

Arakis
26.06.2011 15:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
trashkid2000 trashkid2000 ist männlich
myCSharp.de-Mitglied

Dabei seit: 27.12.2010
Beiträge: 153


trashkid2000 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,
so, habe nochmal meinen Beitrag oben geändert und den Code geändert/ verbessert.
Also die DL-URL wird schonmal korrekt ausgelesen, aber am Download hapert es derzeit noch. Irgendwie erhalte ich keine Response...
Mal schauen, woran es hapert.
26.06.2011 19:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Arakiss
myCSharp.de-Mitglied

Dabei seit: 26.06.2011
Beiträge: 5

Themenstarter Thema begonnen von Arakiss

Arakiss ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich habe es hinbekommen. Auch wenn es ein bisschen improvisiert ist.
Habe den folgenden Code benutzt:

C#-Code:
string requestUri = "http://doc.morningstar.com/LatestDoc.aspx?clientid=on-demand&key=a20d5eed49c96564&language=0L00000122&sid=F0000001W6&dt=52";
Cookie cookie = null;
HttpWebRequest cookieRequest = (HttpWebRequest)WebRequest.Create(requestUri);
cookieRequest.CookieContainer = new CookieContainer();
using (HttpWebResponse cookieResponse = (HttpWebResponse)cookieRequest.GetResponse())
{
    cookie = cookieResponse.Cookies.OfType<Cookie>().FirstOrDefault();
}
if (cookie == null)
    throw new InvalidOperationException("no cookie was received");

String tempUrl = "";
String temprequestcontent;
HttpWebRequest temprequest = (HttpWebRequest)WebRequest.Create(requestUri);
using (StreamReader reader = new StreamReader(temprequest.GetResponse().GetResponseStream()))
{
    while ((temprequestcontent = reader.ReadLine()) != null)
    {
        Console.WriteLine(temprequestcontent);
        if (temprequestcontent.Contains("docheader.aspx?"))
        {
            Console.WriteLine(temprequestcontent);
            Console.WriteLine(temprequestcontent.IndexOf("docheader.aspx?", 20).ToString());
            int anf = temprequestcontent.IndexOf("docheader.aspx?", 20);
            string newS = temprequestcontent.Remove(0, anf);
            newS = newS.Remove(newS.Length - 18);
            tempUrl = @"http://doc.morningstar.com/" + newS;
            Console.WriteLine(newS);
        }
    }
}

HttpWebRequest mainRequest = (HttpWebRequest)WebRequest.Create(tempUrl);

mainRequest.CookieContainer = new CookieContainer();
mainRequest.CookieContainer.Add(cookie);
mainRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

string mainResponseContent;
using (StreamReader reader = new StreamReader(mainRequest.GetResponse().GetResponseStream()))
{
    while ((mainResponseContent = reader.ReadLine()) != null)
    {
        Console.WriteLine(mainResponseContent);
        if (mainResponseContent.Contains("DocDetail") && mainResponseContent.Contains("Document"))
        {
            Console.WriteLine(mainResponseContent);
            Console.WriteLine(mainResponseContent.IndexOf("Document", 30).ToString());
            int anf = mainResponseContent.IndexOf("Document", 30);
            string newS = mainResponseContent.Remove(0,anf);
            newS = newS.Remove(newS.Length - 2);
            tempUrl = @"http://doc.morningstar.com/" + newS;
            Console.WriteLine(newS);
        }
    }
}

mainRequest = (HttpWebRequest)WebRequest.Create(tempUrl);
mainRequest.CookieContainer = new CookieContainer();
mainRequest.CookieContainer.Add(cookie);
mainRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

Stream stream = mainRequest.GetResponse().GetResponseStream();

if (stream != null)
{
    if (File.Exists(@"c:\myfile.pdf"))
        File.Delete(@"c:\myfile.pdf");

    FileStream fs = new FileStream(@"c:\myfile.pdf", FileMode.CreateNew, FileAccess.Write);

    byte[] buffer = new byte[5000];
    int read = 0;

    while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
    {
        fs.Write(buffer, 0, read);
    }

    stream.Close();
    fs.Close();
}

Sieht ein bisschen wüst aus, aber für Schönheit hab ich erst bald wieder Zeit.

Also bei mir läuft das automatisch bis zur fertigen Datei im angegeben Verzeichnis.
Vielen Dank nochmal für die Hilfe!

Gruß,

Arakis
26.06.2011 21:10 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dN!3L dN!3L ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2985.png


Dabei seit: 13.08.2004
Beiträge: 2.891


dN!3L ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Viel Aufwand könntest du dir sparen, indem du die  WebClient-Klasse (System.Net) benutzt. Für Sessions/Cookies gibt's den  WebClient mit HTTP-POST- und Cookie-Unterstützung.
Für das Auffinden der URL würde sich zudem die  Regex-Klasse (System.Text.RegularExpressions) anbieten.
27.06.2011 11:04 Beiträge des Benutzers | zu Buddylist hinzufügen
vagtler vagtler ist männlich
myCSharp.de-Mitglied

Dabei seit: 09.07.2010
Beiträge: 66
Entwicklungsumgebung: Visual Studio, Xcode, Eclipse
Herkunft: Köln


vagtler ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von dN!3L:
Viel Aufwand könntest du dir sparen, indem du die  WebClient-Klasse (System.Net) benutzt. [...]

[offtopic]Klarer Fall von Eingangsposting nicht gelesen?... großes Grinsen [/offtopic]
27.06.2011 13:01 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Arakiss
myCSharp.de-Mitglied

Dabei seit: 26.06.2011
Beiträge: 5

Themenstarter Thema begonnen von Arakiss

Arakiss ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke für die Anregungen, werde ich mir auf jeden Fall genauer anschauen.
Bin aber schon heilfroh, dass es so läuft. Immerhin schon 14 Stunden fehlerfrei ein paar tausend PDFs runter geladen Augenzwinkern
27.06.2011 13:23 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dN!3L dN!3L ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2985.png


Dabei seit: 13.08.2004
Beiträge: 2.891


dN!3L ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



Zitat von vagtler:
[offtopic]Klarer Fall von Eingangsposting nicht gelesen?... :D[/offtopic]

Klarer Fall von selber Eingangsposting nicht verstanden: Das Problem ist nicht der WebClient, sondern das zweistufige Laden. Erst die HTML-Datei holen, dann daraus die eigentliche URL extrahieren und schließlich die richtige PDF-Datei laden.

Das ganze Rumhantiere mit WebRequest & -Response, Streams, usw. macht der WebClient für einen.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dN!3L am 27.06.2011 13:43.

27.06.2011 13:42 Beiträge des Benutzers | zu Buddylist hinzufügen
trashkid2000 trashkid2000 ist männlich
myCSharp.de-Mitglied

Dabei seit: 27.12.2010
Beiträge: 153


trashkid2000 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,
also gegen die Verwendung von WebRequest, WebResponse und Co kann man vielleicht streiten. Aber muss man nicht. So hat man wenigstens volle Kontrolle über das, was geschieht. Schön, dass es immer für alles eine andere Lösung gibt.

Und auch schön, dass es immer welche gibt, die es besser wissen müssen Augenzwinkern
Ist nicht böse gemeint. Aber erst antwortet keiner, und wenn dann eine funktionierende Lösung gepostet wurde, wird diese auch gleich mal auseinandergenommen.

Das große Problem hierbei war das sogar 3-stufige laden der Daten. Und zu verstehen bzw. herauszubekommen, wie die Kommunikation mit der Seite (speziell dem Cookie) erfolgen muss. Mit welcher Technik man dann die Daten von der Seite zieht ist ein anderes Thema.

Das mit den Stringoperationen zum auslesen der Adressen aus den html ist wirklich nicht so schön. Aber eine Variante unter Verwendung regulärer Ausdrücke hatte ich ja oben schon gepostet.
Marko
27.06.2011 14:32 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dN!3L dN!3L ist männlich
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-2985.png


Dabei seit: 13.08.2004
Beiträge: 2.891


dN!3L ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



Zitat von trashkid2000:
Aber erst antwortet keiner, und wenn dann eine funktionierende Lösung gepostet wurde, wird diese auch gleich mal auseinandergenommen

Sorry, das sollte kein auseinandernehmen werden. Das sollte lediglich eine informative Ergänzung sein.
Uns sorry, dass ich Sonntags nicht online war...
27.06.2011 15:16 Beiträge des Benutzers | zu Buddylist hinzufügen
myCSharp.de
Moderationshinweis von MarsStein (27.06.2011 16:51):

Nun lasst wieder gut sein und kommt bitte zum Thema zurück.
 
Arakiss
myCSharp.de-Mitglied

Dabei seit: 26.06.2011
Beiträge: 5

Themenstarter Thema begonnen von Arakiss

Arakiss ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ja wie ich die Strings zerlege, ist echt hässlich, aber hab ja extra dazu geschrieben, dass ich da nur kurz improvisiert habe. Und wie man schön Strings zerlegt, war ja auch nicht das Problem, sondern eben das, wie ich an die Datei komme und das klappt ja Augenzwinkern
27.06.2011 18:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 7 Jahre.
Der letzte Beitrag ist älter als 7 Jahre.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team. Alle Rechte vorbehalten. 23.04.2019 04:23