Jump to content
Guest

[C#]Problema WebBrowser

Recommended Posts

Posted (edited)

Salut,

Am o aplicatie care viziteaza multe pagini de pe OLX si apasa pe butonul de aratat numarul de telefon. Folosesc WebBrowser si totul e bine si frumos, butonul este apasat.

 

Eu dupa ce apas butonul respectiv extrag sursa paginii ca mai apoi cu HTMLAgilityPack sau ceva sa extrag numarul de telefon. Pana acum totul merge bine pentru 1 pagina la un moment dat, dar problema apare cand vreau sa vizitez o lista de pagini pentru a face lucrul respectiv. Cred ca este vina controlului WebBrowser pentru ca se misca foarte incet povestea. Adica ii ia zeci de secunde bune pentru o amarata de pagina sa apese butonul si sa descarce sursa dupa.

 

Sa nu mai spun faptul ca fiind un control ActiveX nu pot sa pasez multithreaded spre el... Aveti idee de altceva care ar putea face click pe acel buton si sa descarc sursa updatata dupa ce s-a executat javascriptul care arata numarul de telefon?

 

Am aici codul cu WebBrowser care face treaba asta:

 

public List<String> Viziteaza(List<String> pagini)
        {
		    List<String> sursePagini = new List<String>();
            WebBrowser wb = new WebBrowser();
            wb.ScriptErrorsSuppressed = true;


          //  wb.AllowNavigation = true;

            foreach (String anunt in pagini)
            {
                //WebBrowser wb = new WebBrowser();
                //wb.ScriptErrorsSuppressed = true;


                //wb.AllowNavigation = true;
                //if (!wb.IsBusy)
                //{
                wb.Navigate(anunt);
                //}
                //while (wb.ReadyState == WebBrowserReadyState.Loading)
                //{


                //    Application.DoEvents();


                //}


                wb.DocumentCompleted += wb_DocumentCompleted;

                while (wb.ReadyState != WebBrowserReadyState.Complete) //treaba asta ingreuneaza povestea dar fara ea nu pot sa iau sursa
                {

                    
                    Application.DoEvents();



                }
                if (wb.ReadyState == WebBrowserReadyState.Complete)
                {
                    
                    StringBuilder htmlcode = new StringBuilder();
                    foreach (HtmlElement item in wb.Document.All)
                    {
                        htmlcode.Append(item.InnerHtml);
                    }

                    
                    sursePagini.Add(htmlcode.ToString());
                    
                }
            }
			
			return sursePagini;

           
        }
		
		void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            HtmlElementCollection links = (sender as WebBrowser).Document.GetElementsByTagName("div");

            foreach (HtmlElement link in links)
            {
                if (link.OuterHtml.ToString().Contains("phone"))
                    link.InvokeMember("click");
            }

        }

 

Edited by Guest
  • Active Members
Posted (edited)

Inainte sa dai click pe buton, pastreaza intr-o variabila innerHTML-u butonului, dupa ce dai click pe buton fa un while care verifica daca innerHTML-u e diferit de cel pe care l-ai memorat inainte, daca e diferit dai break. Sau vezi care e request-ul ce iti da numarul de telefon si il construiesti manual.

Edited by dancezar
Posted (edited)
10 minutes ago, dancezar said:

Inainte sa dai click pe buton, pastreaza intr-o variabila innerHTML-u butonului, dupa ce dai click pe buton fa un while care verifica daca innerHTML-u e diferit ce cel pe care l-ai memorat inainte, daca e diferit dai break. Sau vezi care e request-ul ce iti da numarul de telefon si il construiesti manual.

 

Ideea e ca ei au butonul de apasat ca sa vezi numarul intr-un div. Dupa cum observi eu in cod caut prin toate div-urile si daca gasesc unul sa aiba in OuterHtml "phone" (deci ala care trebuie), apas pe acel div.

 

Un div de genul asta arata cam asa la ei:

 

<div class="contact-button link-phone {'path':'phone', 'id':'9EI91', 'id_raw': '142689839'} atClickTracking contact-a" data-rel="phone">
			<i data-icon="phone"></i>
							<strong class="xx-large">07xx xxx xxx</strong>
				<span class="spoiler">
					Arata telefon				</span>
					</div>

 

Cand apesi pe buton, se mai adauga "activated" la "atClickTacking contact-a" prin ceva javascript si iti arata numarul, asa fac ei ca sa vada ca ai apasat.

 

Ar mai fi o problema esentiala cu WebBrowser. Nu pot sa il folosesc multithreaded iar eu vizitez mii de pagini, deci ar dura foarte mult chiar si asa. Din ce am inteles un WebRequest sau WebClient ar fi mult mai bune, dar nu am idee cum sa fac sa apas butonul, din ce am inteles astea doua pe care le-am mentionat nu au suport pentru scripturi.

Edited by Guest
  • Active Members
Posted (edited)
32 minutes ago, aismen said:

 

Ideea e ca ei au butonul de apasat ca sa vezi numarul intr-un div. Dupa cum observi eu in cod caut prin toate div-urile si daca gasesc unul sa aiba in OuterHtml "phone" (deci ala care trebuie), apas pe acel div.

 

Un div de genul asta arata cam asa la ei:

 


<div class="contact-button link-phone {'path':'phone', 'id':'9EI91', 'id_raw': '142689839'} atClickTracking contact-a" data-rel="phone">
			<i data-icon="phone"></i>
							<strong class="xx-large">07xx xxx xxx</strong>
				<span class="spoiler">
					Arata telefon				</span>
					</div>

 

Cand apesi pe buton, se mai adauga "activated" la "atClickTacking contact-a" prin ceva javascript si iti arata numarul, asa fac ei ca sa vada ca ai apasat.

 

Ar mai fi o problema esentiala cu WebBrowser. Nu pot sa il folosesc multithreaded iar eu vizitez mii de pagini, deci ar dura foarte mult chiar si asa. Din ce am inteles un WebRequest sau WebClient ar fi mult mai bune, dar nu am idee cum sa fac sa apas butonul, din ce am inteles astea doua pe care le-am mentionat nu au suport pentru scripturi.

Uite faza, in pagina HTML din anunt exista un token:

<script>var phoneToken ='...';</script>

Asta e folosit in request-ul:

https://www.olx.ro/ajax/misc/contact/phone/6u9qo/?pt=4a124a3ce5aa3a4e734101e05b2d19e4d85447793dcabe3f73f7f6c6ae20481600f57e7acf440bd9f9b79e458d44e1507e33e8b4d47b9af6fad8fb2e1798ac6a

 

Token-ul pe care il agati cu un regex il introduci in URL si in cookie fiindca altfel iti va da numarul gol.

Ca si proof of concept, uite ceva schitat in python:

 

import re
import requests
ID="6u9qo"
url='https://www.olx.ro/oferta/realizare-site-web-de-informare-si-profesionale-domeniu-webhosting-ID'+ID+'.html'

s=requests.session()

first=s.get(url,headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"})
html=first.content
token=re.findall("var phoneToken = \'(.*?)\';",html)

if len(token)==0:
    print 'token...'
    exit()
token=token[0]
print token
s.cookies.set('pt',token)

request_nr=s.get('https://www.olx.ro/ajax/misc/contact/phone/'+ID+'/?pt='+token,headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"})

html=request_nr.content
print html

Ce nu trebuie sa uiti este sa bagi o sesiune.

Edited by dancezar
Posted
Just now, jetus said:

Il am in php cu mysql pe categorii cu tot ce trebuie, 100euro daca te intereseaza.  

Nu, multumesc, vreau sa scriu aplicatia mea dar am dat peste acel impas. Sper sa reusesc cu ce mi-a recomandat dancezar.

Posted
1 hour ago, dancezar said:

Uite faza, in pagina HTML din anunt exista un token:


<script>var phoneToken ='...';</script>

Asta e folosit in request-ul:

https://www.olx.ro/ajax/misc/contact/phone/6u9qo/?pt=4a124a3ce5aa3a4e734101e05b2d19e4d85447793dcabe3f73f7f6c6ae20481600f57e7acf440bd9f9b79e458d44e1507e33e8b4d47b9af6fad8fb2e1798ac6a

 

Token-ul pe care il agati cu un regex il introduci in URL si in cookie fiindca altfel iti va da numarul gol.

Ca si proof of concept, uite ceva schitat in python:

 


import re
import requests
ID="6u9qo"
url='https://www.olx.ro/oferta/realizare-site-web-de-informare-si-profesionale-domeniu-webhosting-ID'+ID+'.html'

s=requests.session()

first=s.get(url,headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"})
html=first.content
token=re.findall("var phoneToken = \'(.*?)\';",html)

if len(token)==0:
    print 'token...'
    exit()
token=token[0]
print token
s.cookies.set('pt',token)

request_nr=s.get('https://www.olx.ro/ajax/misc/contact/phone/'+ID+'/?pt='+token,headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"})

html=request_nr.content
print html

Ce nu trebuie sa uiti este sa bagi o sesiune.

 

 

Uite, am facut cum ai spus tu pe exemplul tau, i-am pasat cookieul care trebuie, insa tot imi intoarce 000000 ca si cum nu i-as fi dat cookie cum trebuie

 

string html = string.Empty;
            string url = @"https://www.olx.ro/ajax/misc/contact/phone/6u9qo/?pt=81c0388900c4b9f667d9258ae7148fb8636b69b658609a0cd94198b99a6b9192faa6d9420513d6d2d530117e1d3504e7f95daa9d50069a0222be8145eec05bd9";


            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.AutomaticDecompression = DecompressionMethods.GZip;
            request.AllowAutoRedirect = true;
            

            request.CookieContainer = new CookieContainer();
            request.CookieContainer.Add(new Cookie("pt", "81c0388900c4b9f667d9258ae7148fb8636b69b658609a0cd94198b99a6b9192faa6d9420513d6d2d530117e1d3504e7f95daa9d50069a0222be8145eec05bd9") { Domain = "www.olx.ro" });
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0";
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            using (Stream stream = response.GetResponseStream())
            using (StreamReader reader = new StreamReader(stream))
            {
                html = reader.ReadToEnd();
            }

            richTextBox1.Text = html;

 

 

  • Active Members
Posted
4 minutes ago, aismen said:

 

 

Uite, am facut cum ai spus tu pe exemplul tau, i-am pasat cookieul care trebuie, insa tot imi intoarce 000000 ca si cum nu i-as fi dat cookie cum trebuie

 


string html = string.Empty;
            string url = @"https://www.olx.ro/ajax/misc/contact/phone/6u9qo/?pt=81c0388900c4b9f667d9258ae7148fb8636b69b658609a0cd94198b99a6b9192faa6d9420513d6d2d530117e1d3504e7f95daa9d50069a0222be8145eec05bd9";


            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.AutomaticDecompression = DecompressionMethods.GZip;
            request.AllowAutoRedirect = true;
            

            request.CookieContainer = new CookieContainer();
            request.CookieContainer.Add(new Cookie("pt", "81c0388900c4b9f667d9258ae7148fb8636b69b658609a0cd94198b99a6b9192faa6d9420513d6d2d530117e1d3504e7f95daa9d50069a0222be8145eec05bd9") { Domain = "www.olx.ro" });
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0";
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            using (Stream stream = response.GetResponseStream())
            using (StreamReader reader = new StreamReader(stream))
            {
                html = reader.ReadToEnd();
            }

            richTextBox1.Text = html;

 

 

 

Acel token se schimba mereu nu e static, si este legat de o sesiune "PHPSessid". Trebuie sa faci un CookieJar iar toate cookie-urile din primul request sa fie trimise si catre al doilea request. Daca am timp si nu reusesti o sa il scriu si in c#.

Posted
24 minutes ago, dancezar said:

 

Acel token se schimba mereu nu e static, si este legat de o sesiune "PHPSessid". Trebuie sa faci un CookieJar iar toate cookie-urile din primul request sa fie trimise si catre al doilea request. Daca am timp si nu reusesti o sa il scriu si in c#.

 

 

Am reusit. Uite:

 

CookieContainer cookies = new CookieContainer();
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://www.olx.ro/oferta/realizare-site-web-de-informare-si-profesionale-domeniu-webhosting-ID6u9qo.html");
            webRequest.CookieContainer = cookies;
            
            webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0";
            HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
            StreamReader responseReader = new StreamReader(response.GetResponseStream());

            string sResponseHTML = responseReader.ReadToEnd();

            string pattern = @"var phoneToken = \'(.*?)\';";
            string token = string.Empty;
            MatchCollection matches = Regex.Matches(sResponseHTML, pattern);
            foreach (Match match in matches)
            {
                token = match.Groups[1].Value;
            }
            Uri target = new Uri("https://www.olx.ro/ajax/misc/contact/phone/6u9qo/?pt=" + token);
            HttpWebRequest nrRequest = (HttpWebRequest)WebRequest.Create("https://www.olx.ro/ajax/misc/contact/phone/6u9qo/?pt="+token);
            nrRequest.CookieContainer = cookies;
            nrRequest.CookieContainer.Add(new Cookie("pt", token) { Domain = target.Host });
            nrRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0";
            HttpWebResponse nrResponse = (HttpWebResponse)nrRequest.GetResponse();

            StreamReader nrReader = new StreamReader(nrResponse.GetResponseStream());

            string nrResponseHTML = nrReader.ReadToEnd();

            richTextBox1.Text = nrResponseHTML;

Si intoarce numarul care trebuie. Secretul era ca trebuia sa fiu pe aceeasi sesiune cand extrageam tokenul si cand il bagam in cookie, si asta s-a realizat pastrand cookieurile din sesiunea in care am extras tokenul. Acum da nr care trebuie. Multumesc pentru indrumari.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...