Подтвердить что ты не робот

Использование WebClient в С# есть способ получить URL-адрес сайта после перенаправления?

Используя класс 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?

4b9b3361

Ответ 1

Если я понимаю этот вопрос, это намного проще, чем люди говорят - если вы хотите, чтобы 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), если вы использовали материал async.

Ответ 2

Я знаю, что это уже ответ на вопрос, но это работает довольно мне:

 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);

Приветствие.!;)

Ответ 3

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

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

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

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

Ответ 4

Я получил 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();

Ответ 5

Если вас интересует только 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"];
     }
}

Метод вернет

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

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

Ответ 6

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();  

Ответ 7

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

Ответ 8

Хорошо, это действительно хакерство, но ключ должен использовать 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