Html 민첩성 팩, 웹 스크래핑 및 스푸핑 C #

c# html-agility-pack spoofing web-scraping

문제

C # 코드에서 웹 요청을 스푸핑 할 수있는 방법이있어 사이트를 공격하는 봇이나 스팸처럼 보이지 않습니까? 나는 웹 사이트를 긁어 내려고 노력하고 있지만 일정량의 통화가 끝나면 계속 차단됩니다. 나는 진짜 브라우저처럼 행동하고 싶다. HTML Agility Pack에서이 코드를 사용하고 있습니다.

 var web = new HtmlWeb();
                web.UserAgent =
                    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11";

수락 된 답변

일반 브라우저 및 피들러 (개발자 도구가 긁히지 않는 경우)를 사용하여 요청 및 응답 헤더를 살펴보십시오.

요청을 빌드하고 헤더가 브라우저가 보내는 것과 일치하도록 요청하십시오 (차이가 나는지 확인하기 위해 여러 브라우저를 사용할 수 있습니다).

"일정량의 통화 후 차단됨"과 관련하여 통화를 차단하십시오. x 초마다 한 번만 전화하십시오. 사이트를 잘 작동하면 잘 작동합니다.

초당 IP 주소로 걸려 오는 전화의 수를 살펴보고 임계 값을 초과하면 IP 주소가 차단 될 가능성이 있습니다.


인기 답변

너무 많은 웹 스크래핑을하지만, 여기에 옵션이 있습니다 : 나는 브라우저에서 기대되는 모든 추가 헤더의 기본 목록을 가지고 있습니다.

        wc.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11";
        wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
        wc.Headers[HttpRequestHeader.Accept] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        wc.Headers[HttpRequestHeader.AcceptEncoding] = "gzip,deflate,sdch";
        wc.Headers[HttpRequestHeader.AcceptLanguage] = "en-GB,en-US;q=0.8,en;q=0.6";
        wc.Headers[HttpRequestHeader.AcceptCharset] = "ISO-8859-1,utf-8;q=0.7,*;q=0.3";

(WC는 제 웹 클라이언트입니다).

추가 도움 - 쿠키를 저장하는 웹 클라이언트 클래스가 있습니다 - 또한 큰 도움이됩니다.

public class CookieWebClient : WebClient
{

    public CookieContainer m_container = new CookieContainer();
    public WebProxy proxy = null;

    protected override WebRequest GetWebRequest(Uri address)
    {
        try
        {
            ServicePointManager.DefaultConnectionLimit = 1000000;
            WebRequest request = base.GetWebRequest(address);
            request.Proxy = proxy;

            HttpWebRequest webRequest = request as HttpWebRequest;
            webRequest.Pipelined = true;
            webRequest.KeepAlive = true;
            if (webRequest != null)
            {
                webRequest.CookieContainer = m_container;
            }

            return request;
        }
        catch
        {
            return null;
        }
    }
}

여기에 내 평소 사용하고 있습니다. 가능성이있는 모든 파싱 함수를 사용하여 기본 사이트 클래스에 정적 복사본을 추가하십시오.

    protected static CookieWebClient wc = new CookieWebClient();

그리고 그것을 다음과 같이 부르십시오.

public HtmlDocument Download(string url)
    {
        HtmlDocument hdoc = new HtmlDocument();
        HtmlNode.ElementsFlags.Remove("option");
        HtmlNode.ElementsFlags.Remove("select");
        Stream read = null;
        try
        {
            read = wc.OpenRead(url);
        }
        catch (ArgumentException)
        {
            read = wc.OpenRead(HttpHelper.HTTPEncode(url));
        }

        hdoc.Load(read, true);


        return hdoc;
    }

다른 주요 원인은 너무 오래 열려있어 연결이 서버에 의해 닫혀 있다는 것입니다. 위와 같이 다운로드 부분 주위에 try catch를 추가하여이를 증명할 수 있습니다. 실패한 경우 웹 클라이언트를 재설정하고 다시 다운로드하십시오.

HtmlDocument d = new HtmlDocument();
                            try
                            {
                                d = this.Download(prp.PropertyUrl);
                            }
                            catch (WebException e)
                            {
                                this.Msg(Site.ErrorSeverity.Severe, "Error connecting to " + this.URL + " : Resubmitting..");
                                wc = new CookieWebClient();
                                d = this.Download(prp.PropertyUrl);
                            }

이것은 내 엉덩이를 항상 절약 할 수 있습니다. 서버가 사용자를 거부하더라도이 작업은 많은 작업을 수행 할 수 있습니다. 쿠키는 지워지고 자유롭게 돌아 다닐 수 있습니다. 더 나쁜 상황이 진정 악화되면 - 프록시 지원을 추가하고 50-ish 요청마다 새 프록시를 적용하십시오.

그만큼 자신이나 다른 사이트를 걷어차기에 충분합니다.

나를 평가!



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.