Automazione scaricamento pdf - Scraping

lunedì 16 aprile 2012 - 23.16
Tag Elenco Tags  C#  |  .NET 3.0  |  .NET 3.5  |  Visual Studio 2008

alvisi.matteo Profilo | Newbie

Salve a tutti, vi pongo alcune problematiche che non mi fanno dormre la notte.
Per l azienda per cui lavoro ho la necessità di automatizzare lo scaricamento di fatture dal sito di un nostro fornitore (https://www.axxes.fr/it/).
Qualcuno sa darmi qualche dritta?Ho provato diversi tutorial ma senza avere successo.Uno degli errori più frequenti è " sono stati eseguiti troppi reindirizzamenti automatici"

Problema n°1
Ho provato ad utilizzare Watin ma mi sono arenato in una pagina con una tabella:

Data Estratto fatture
03 aprile 2012 Distinta fattura N : 001033064
19 marzo 2012 Distinta fattura N : 001020302
05 marzo 2012 Distinta fattura N : 001008408
20 febbraio 2012 Distinta fattura N : 000995926
03 febbraio 2012 Distinta fattura N : 000984264

Dovrei prendere le distinte fatture relative ad un determinato mese(La colonna estratto fatture sono tutti link).Come posso fare in modo automatizzato?

Problema n°2
Arrivo alla pagina finale e ho i link alle fatture che sono di questo tipo: https://www.axxes.fr/it/client/pge1_relevefacturepdf.aspx?selnumdoc=700051126&typ=FTR&lng=ES&famdoc=FTR&typfic=PDF
Il PDF viene generato in automatico on the fly. Come posso fare a salvare in automatico il pdf senza iterazione da parte dell utente?

Grazie in anticipo per l'aiuto

massimo.missaglia Profilo | Newbie

Giusto per iniziare proverei con questo

http://www.massimomissaglia.com/Pages/Contents.aspx?Cod=9&Pid=9&Title=Download+di+una+pagina+web

dove puoi "scaricare" una pagina poi vedi il contenuto...

private void Download()
{
String HTML=GetPage("http://www.MassimoMissaglia.com/Articoli.aspx");
StreamWriter writeStream = new StreamWriter(Server.MapPath(".") + "/Articoli.htm");
writeStream.Write(HTML);
writeStream.Close();
}

private String GetPage(String Url)
{
String ReturnText = "";

HttpWebRequest Requester = (HttpWebRequest)WebRequest.Create(Url);

var _with1 = Requester;
_with1.ContentType = "text/plain";
_with1.Method = "Get";
_with1.Timeout = 10000;
HttpWebResponse WebResponse = (HttpWebResponse)Requester.GetResponse();

if (WebResponse.StatusCode == HttpStatusCode.OK)
{
StreamReader readStream = new StreamReader(WebResponse.GetResponseStream(), Encoding.UTF8);
ReturnText= readStream.ReadToEnd();
}

WebResponse.Close();
return ReturnText;
}

InsettoScoppiettato Profilo | Junior Member

il codice (provato.. funziona) è il seguente:

per il codice del form:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Per il designer del form:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


TI ho creato un form con 6 pulsanti, il primo per andare sulla pagina attraverso un bwebrowser
il secondo invece ti manda sull'area utenti
il terzo di fa il login e poi mi sono fermato perchè non ho username e password, ma ti posso dire che cosa avrei fatto io.
1) una volta entrato avrei cercato di navigare fino alla lista delle fatture, trovato tutti i links e messi in una lista di HtmlElement.
2) in un grosso ciclo for ( sulla lista dei link) avrei eseguito un metodo che chiama le seguenti subs:
2.1) invoca il link e attendi che il pdf si generi.
2.2) salvo con nome il pdf
2.3) preparo lal pagina come era prima del punto 2.1 in modo che la prossima iterazione del ciclo for funzioni

Spero di esserti stato utile.
ciao

Alessandro Parma
Programmazione multipla scoposta con prognosi ancora da definire

alvisi.matteo Profilo | Newbie

Ciao Massimo, grazie per la risposta. Il mio problema è che la soluzione che mi hai proposto è per un sito http e non https.....

alvisi.matteo Profilo | Newbie

Ciao Insetto, prima di tutto grazie mille per la risposta. A livello di webbrowser sono riuscito ad arrivare fino alla lista delle fatture poi mi sono arenato al fatto dello scaricamento. I link delle fatture sono tutti di questo tipo: https://www.axxes.fr/it/client/pge1_relevefacturepdf.aspx?selnumdoc=700051126&typ=FTR&lng=ES&famdoc=FTR&typfic=PDF l'unica cosa che cambia è il selnumdoc. Una volta cliccato restituisce sempre lo stesso nome di file e poi non so come poter scaricare il pdf in automatico su disco.

Qualcuno ha qualche idea???

InsettoScoppiettato Profilo | Junior Member

Qui trovi qualche hint su come usare il webBriwser in questo modo:
http://www.codeproject.com/Articles/18935/The-most-complete-C-Webbrowser-wrapper-control

anyhow, sembra che la maniera migliore, una volta entrato nel sito sia usare un webCLient, che espone il metodo FIledownload (vedi http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.80).aspx e http://social.msdn.microsoft.com/Forums/en/winforms/thread/259a91a8-8b49-4ffd-adc6-ea58ac3538fb).
COmunque, io proverei prima aprocedere con la stessa logica con cui ho creato i primi button:
IN in pratica io farei

wb.Document.GetElementById("id del tuo primo link").InvokeMember("click");
oppure con la reflection come facevo nei listati messi nei precedenti post (che è meglio anche per fare debug: InvokeMember("click") non fa nulla se l'evento click non esiste, la reflection invece genera eccezione e la vedi subito).
MI sa che però ti apre una finestra di salvataggio file.

fammi sapere, non ho mai provato e la cosa può essere interessante.

ciauz
Ale
Alessandro Parma
Programmazione multipla scoposta con prognosi ancora da definire

alvisi.matteo Profilo | Newbie

Ciao Alessandro, ho provato con la classe wb ma niente da fare mi apre direttamente il pdf...quindi questa strada non è praticabile in quanto ho bisogno di salvarli in automatico

Ho provato il wrapper che mi hai indicato ma non riesco a registrare la dll con w7 64bit...
Le uniche strade che mi rimangono da percorrere sono webclient e httprequest... ho provato il seguente codice:

// this is what we are sending
string post_data = "_cm_url=/it/client/default.aspx&_cm_user=user&_cm_pwd=pwd";

// this is where we will send it
string uri = "https://www.axxes.fr/it/identification/default.cgi";

// create a request
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(uri); request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "POST";

// turn our request string into a byte stream
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);

// this is important - make sure you specify type this way
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
System.Net.ServicePointManager.CertificatePolicy= new MyPolicy();
Stream requestStream = request.GetRequestStream();

// now send it
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();

// grab te response and print it out to the console along with the status code
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
listBox1.Text=(new StreamReader(response.GetResponseStream()).ReadToEnd());
Console.WriteLine(response.StatusCode);
}
public class MyPolicy : ICertificatePolicy
{
public bool CheckValidationResult(ServicePoint srvPoint,
X509Certificate certificate, WebRequest request,
int certificateProblem)
{
//Return True to force the certificate to be accepted.
return true;
}
}

Niente da fare non riesco a loggarmi mi restituisce la pagina iniziale di login. Con Fiddler ho provato ad analizzare il traffico di una navigazione da browser e questo è quanto:
Digito logine e password e clicco Connetti

1
POST /it/identification/default.cgi HTTP/1.1
_cm_url=%2Fit%2Fclient%2Fdefault.aspx&_cm_user=user&_cm_pwd=password&btOk.x=23&btOk.y=12

2
GET /it/client/default.aspx HTTP/1.1
ASP.NET_SessionId=3hbcfrzstvxwo145tpgpvmvw
IdSes=4fba1069405c428bab1........

3
GET /it/client/pge1_clientrecherche.aspx HTTP/1.1
ASP.NET_SessionId=3hbcfrzstvxwo145tpgpvmvw
IdSes=4fba1069405c428.............


Mentre con il codice che ho postato fa solo una richiesta al CGI.
Sinceramente non riesco a capire come poter accedere. Sembra come manchi qualcosa..il cookie?Come gestirlo? Avete qualche tips?

Qualche idea?
Thanx again

InsettoScoppiettato Profilo | Junior Member

Beh, era quello che avrei voluto fare io nel tuo caso.
Aprire il link del pdf, lasciare (o melgio sperare che il webbrowser lo visualizzasse) e poi trovare un modo per fare qualcosa del tipo "Salva con nome".
Non mi sono mai trovato in questa situazione, ti consiglio di partire dai link the ti ho dato per studiare la cosa, comunque un hint che posso lasciarti io è questo:
- guarda se nell'html dellapagina c'è tutto il minario del file.. in tal caso basta che salvi lo stream di quel tag su un nuovo file

ciao

Alessandro Parma
Programmazione multipla scoposta con prognosi ancora da definire

InsettoScoppiettato Profilo | Junior Member

Forse ho trovato la soluzione:

http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/d338a2c8-96df-4cb0-b8be-c5fbdd7c9202/?prof=required

http://stackoverflow.com/questions/1145426/automated-filedownload-using-webbrowser-without-url


ciao
Ale

Alessandro Parma

alvisi.matteo Profilo | Newbie

Purtroppo il tips che mi hai dato l'avevo già trovato. Il problema è che il mio pdf viene generato onthefly e il link è fatto così https://www.axxes.fr/it/client/pge1_relevefacturepdf.aspx?selnumdoc=700051126&typ=FTR&lng=ES&famdoc=FTR&typfic=PDF. Tra l'altroil tips che mi hai mandato prevede l'uso dell'oggetto Webclient che restituisce la pagina di login in quanto la connessione https è stata instaurata tramite l'oggetto webbrowser. Comunque grazie. Conosci dei forum in inglese validi? Sinceramente non so proprio come fare...

InsettoScoppiettato Profilo | Junior Member

prova a vedere su stackoverflow, intando guardo anche io se trovo qualcosa...

Alessandro Parma

alvisi.matteo Profilo | Newbie

ok inserito post anche su stackoverflow e c# corner

InsettoScoppiettato Profilo | Junior Member

Guarda uesto post di DNH... http://www.dotnethell.it/forum/messages.aspx?ThreadID=40778

QUi lui usa un webclient con la funzione DownloadFileAsync che prende giusto il tuo url.
Sembra che riesca anche a gestire le credensiali di accesso al sito.

Probabimente questo risolve il tuo problema se rinunci al webBrowser e passi al WebClient.

ciao

Alessandro Parma

alvisi.matteo Profilo | Newbie

Salve ragazzi, sono riuscito grazie alla libreria Curl per .net a loggarmi su un sito https ssl e riuscire a scaricare i pdf che mi interessano. Non so se può interessare ma, se volete, posso postare il codice. Ho riadattato uno script php datomi dal mitico Paolo Seleis, che ringrazio immensamente, in c#.

InsettoScoppiettato Profilo | Junior Member

SI certo, può sempre servire. posta, posta...

Alessandro Parma
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5