Использование WebClient в C # Есть ли способ получить URL сайта после перенаправления? - PullRequest
40 голосов
/ 27 марта 2009

Используя класс WebClient, я достаточно легко могу получить название сайта:

WebClient x = new WebClient();    
string source = x.DownloadString(s);
string title = Regex.Match(source, 
    @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>",
    RegexOptions.IgnoreCase).Groups["Title"].Value;

Я хочу сохранить URL и заголовок страницы. Однако при переходе по ссылке, такой как:

http://tinyurl.com/dbysxp

Я определенно захочу получить URL, на который я перенаправлен.

ВОПРОСЫ

Есть ли способ сделать это с помощью класса WebClient?

Как бы я это сделал, используя HttpResponse и HttpRequest?

Ответы [ 8 ]

65 голосов
/ 29 марта 2009

Если я понимаю вопрос, это намного проще, чем говорят люди - если вы хотите, чтобы WebClient выполнил все детали запроса (включая перенаправление), но затем получил фактический ответ В конце URI вы можете создать подкласс WebClient следующим образом:

class MyWebClient : WebClient
{
    Uri _responseUri;

    public Uri ResponseUri
    {
        get { return _responseUri; }
    }

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

Просто используйте MyWebClient везде, где бы вы ни использовали WebClient. После того, как вы сделали любой вызов WebClient, который вам нужно было сделать, вы можете просто использовать ResponseUri для получения фактического перенаправленного URI. Вам также необходимо добавить аналогичное переопределение для GetWebResponse (запрос WebRequest, результат IAsyncResult), если вы использовали асинхронный материал.

16 голосов
/ 18 декабря 2011

Я знаю, что это уже ответ на вопрос, но мне это нравится:

 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://tinyurl.com/dbysxp");
 request.AllowAutoRedirect = false;
 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 string redirUrl = response.Headers["Location"];
 response.Close();

 //Show the redirected url
 MessageBox.Show("You're being redirected to: "+redirUrl);

Ура.! ;)

6 голосов
/ 27 марта 2009

При HttpWebRequest вы можете установить для свойства AllowAutoRedirect значение false. Когда это происходит, любой ответ с кодом состояния между 300-399 не будет автоматически перенаправлен.

Затем вы можете получить новый URL-адрес из заголовков ответа, а затем создать новый экземпляр HttpWebRequest для нового URL-адреса.

С WebClient классом я сомневаюсь, что вы можете изменить его "из коробки", чтобы он не разрешал перенаправления. Что вы можете сделать, это извлечь класс из класса WebClient, а затем переопределить методы GetWebRequest и GetWebResponse, чтобы изменить WebRequest / WebResponse экземпляры, которые возвращает базовая реализация; если это HttpWebRequest, установите для свойства AllowAutoRedirect значение false. В ответе, если код состояния находится в диапазоне 300-399, введите новый запрос.

Однако я не знаю, что вы можете отправить новый запрос из методов GetWebRequest / GetWebResponse, поэтому может быть лучше просто иметь цикл, который выполняется с HttpWebRequest / HttpWebResponse, пока не будут выполнены все перенаправления.

3 голосов
/ 19 января 2013

У меня есть Uri для перенаправленной страницы и содержимого страницы.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strUrl);
request.AllowAutoRedirect = true;

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();

strLastRedirect = response.ResponseUri.ToString();

StreamReader reader = new StreamReader(dataStream);              
string strResponse = reader.ReadToEnd();

response.Close();
2 голосов
/ 15 апреля 2015

Если вас интересует только URI перенаправления, вы можете использовать этот код:

public static string GetRedirectUrl(string url)
{
     HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(url);
     request.AllowAutoRedirect = false;

     using (HttpWebResponse response = HttpWebResponse)request.GetResponse())
     {
         return response.Headers["Location"];
     }
}

Метод вернет

  • ноль - в случае отсутствия перенаправления
  • относительный URL - в случае перенаправления

Обратите внимание : оператор using (или окончательный response.close()) имеет важное значение. Подробнее см. Библиотека MSDN . В противном случае вы можете исчерпать соединения или получить тайм-аут при выполнении этого кода несколько раз.

0 голосов
/ 27 марта 2009

Хорошо, это действительно хакерский, но ключ должен использовать HttpWebRequest и затем установить для свойства AllowAutoRedirect значение true.

Вот ОЧЕНЬ взломанный вместе пример

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://tinyurl.com/dbysxp");
        req.Method = "GET";
        req.AllowAutoRedirect = true;
        WebResponse response = req.GetResponse();

        response.GetResponseStream();
        Stream responseStream = response.GetResponseStream();

        // Content-Length header is not trustable, but makes a good hint.
        // Responses longer than int size will throw an exception here!
        int length = (int)response.ContentLength;

        const int bufSizeMax = 65536; // max read buffer size conserves memory
        const int bufSizeMin = 8192;  // min size prevents numerous small reads

        // Use Content-Length if between bufSizeMax and bufSizeMin
        int bufSize = bufSizeMin;
        if (length > bufSize)
            bufSize = length > bufSizeMax ? bufSizeMax : length;

        StringBuilder sb;
        // Allocate buffer and StringBuilder for reading response
        byte[] buf = new byte[bufSize];
        sb = new StringBuilder(bufSize);

        // Read response stream until end
        while ((length = responseStream.Read(buf, 0, buf.Length)) != 0)
            sb.Append(Encoding.UTF8.GetString(buf, 0, length));

        string source = sb.ToString();string title = Regex.Match(source, 
        @"\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>",RegexOptions.IgnoreCase).Groups["Title"].Value;

enter code here

0 голосов
/ 27 марта 2009

HttpWebRequest.AllowAutoRedirect может иметь значение false. Тогда вам придется вручную http коды состояния в диапазоне 300.

// Create a new HttpWebRequest Object to the mentioned URL.
HttpWebRequest myHttpWebRequest=(HttpWebRequest)WebRequest.Create("http://www.contoso.com");    
myHttpWebRequest.MaximumAutomaticRedirections=1;
myHttpWebRequest.AllowAutoRedirect=true;
HttpWebResponse myHttpWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse();  
0 голосов
/ 27 марта 2009

Класс WebClient имеет возможность следовать перенаправлениям. Установите эту опцию, и все будет в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...