Skocz do zawartości

[c#] Przesyłanie sesji między Selenium, a HttpWebRequest


Rekomendowane odpowiedzi

Obsługuję przez Selenium pewną stronę internetową. I na pewnym etapie automatyzacji muszę sprawdzić, czy obrazki o pewnych adresach URL istnieją na danej stronie. Dosyć prosta sprawa, zrobiłem HttpWebRequest i wszystko działa. W praktyce pojawił się jednak problem. Część obrazków jest widoczna tylko dla zalogowanych użytkownik, a więc nie będąc zalogowanym otrzymam zawsze 404 niezależnie, czy taki obrazek na serwerze będzie istniał, czy nie. W przeglądarce z poziomu Selenium(ChromeDriver) jestem na tym etapie automatyzacji zalogowany. Natomiast wyszukuję obrazka z poziomu HttpWebRequest, bo wolałbym, żeby nie odbywało się to na zasadzie otwierania nowej karty przez Selenium i szukania 404, bądź obrazka pod danym URL. Chciałem, żeby to się działo możliwie szybko i "w tle". Czy jest jakieś rozwiązanie na to? Dla utrudnienia dodam, że w Selenium otwieram przeglądarkę w trybie incognito, żeby kilka sesji programu nie gryzło się ze sobą przez wspólne ciasteczka. Domyślam się jednak, że to wcale nie ułatwia sprawy.

 

@Edit: sprawa rozwiązana, ale nie widzę opcji ani usuń temat, ani zamknij, więc nie wiem co z tym zrobić :/

Odnośnik do komentarza
Udostępnij na innych stronach

Na podstawie Stacka, lekko zmodyfikowany kod do moich potrzeb:

WebClientEx myWebClient = new WebClientEx(new CookieContainer());
CookieCollection cc = new CookieCollection();
foreach (OpenQA.Selenium.Cookie cook in driver.Manage().Cookies.AllCookies)
{
  System.Net.Cookie cookie = new System.Net.Cookie();
  cookie.Name = cook.Name;
  cookie.Value = cook.Value;
  cookie.Domain = cook.Domain;
  cc.Add(cookie);
}
myWebClient.CookieContainer.Add(cc);
try
{
  using (var client = myWebClient)
  {
    string s1 = client.DownloadString(_url);
  }
}
catch(NullReferenceException)
{
  return false;
}
return true;

I kod klasy WebClientEx(ze stacka 1:1):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;

namespace mbot
{
    public class WebClientEx : WebClient
    {
        public WebClientEx(CookieContainer container)
        {
            this.container = container;
        }

        public CookieContainer CookieContainer
        {
            get { return container; }
            set { container = value; }
        }

        private CookieContainer container = new CookieContainer();

        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest r = base.GetWebRequest(address);
            var request = r as HttpWebRequest;
            if (request != null)
            {
                request.CookieContainer = container;
            }
            return r;
        }

        protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
        {
            WebResponse response = base.GetWebResponse(request, result);
            ReadCookies(response);
            return response;
        }

        protected override WebResponse GetWebResponse(WebRequest request)
        {
            WebResponse response = base.GetWebResponse(request);
            ReadCookies(response);
            return response;
        }

        private void ReadCookies(WebResponse r)
        {
            var response = r as HttpWebResponse;
            if (response != null)
            {
                CookieCollection cookies = response.Cookies;
                container.Add(cookies);
            }
        }
    }
}

Przy czym nie odpowiadam za 100% poprawne działanie, bo w moim wypadku okazało się, że nie do końca jeszcze na tym etapie potrzebuję jednak być zalogowanym, ponieważ te obrazki które zczytywałem jednak nie wymagały bycia zalogowanym. Więc funkcja jest, ale nie miałem okazji przetestować jej w akcji. Może się jeszcze taka sytuacja nadarzy.

Natomiast samo sprawdzanie, czy nie ma błędu 404, w tle, bez korzystania z selenium, z użyciem HttpWebRequest(nie ma potrzeby otwierania dodatkowej przeglądarki, czy karty) wygląda u mnie tak:

try
{
  var request = (HttpWebRequest)WebRequest.Create(url);
  request.Credentials = CredentialCache.DefaultCredentials;
  request.Method = "HEAD";
  var response = (HttpWebResponse)request.GetResponse();
  return response.StatusCode == HttpStatusCode.OK;
}
catch (Exception)
{
  return false;
}

 

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...