scrapy 는 Ajax 를 이용 하여 갈고리 망 을 기어 오 르 는 문제 총 결

1. 유 료 IP 에이전트 사용 (아부 클 라 우 드 의 동적 HTTP 터널, 요청 할 때마다 자동 으로 IP 전환) 2. User 교체Agent 3. 헤더 내용 보완 (어떤 항목 이 부족 하면 파충류 로 이 어 질 지 확실 하지 않 음)
USER_AGENTS = [
    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
    "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
    "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
    "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
    "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
    "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
    "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
    "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
    "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
]

proxyServer = "http://http-dyn.abuyun.com:9020"

proxyUser = "H201144R93N43URD"
proxyPass = "4BE2A6B831CDDEC7"

proxyAuth = "Basic " + base64.urlsafe_b64encode(bytes((proxyUser + ":" + proxyPass), "ascii")).decode("utf8")

class ProxyMiddleware(object):
    def process_request(self, request, spider):
        request.meta["proxy"] = proxyServer
        request.headers["Proxy-Authorization"] = proxyAuth
        request.headers['User-Agent']=random.choice(USER_AGENTS)
        request.headers['Host']='www.lagou.com'
        request.headers['Origin']='https://www.lagou.com'
        request.headers['Referer']="https://www.lagou.com/jobs/list_"
        request.headers['X-Anit-Forge-Code']='0'
        request.headers['X-Anit-Forge-Token']=None
        request.headers['X-Requested-With']="XMLHttpRequest"
        request.headers['Accept']='application/json, text/javascript, */*; q=0.01'
        request.headers['Accept-Encoding']='gzip, deflate, br'
        request.headers['Accept-Language']='zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7'

4. 동적 쿠키 설정 (모든 request 에 쿠키 를 설정 해 야 합 니 다. 아래 는 하나만 보 여 줍 니 다)
uid 라 이브 러 리 로 무 작위 수 를 만 들 고 scrapy 에 동적 쿠키 를 설정 하 는 것 이 중요 합 니 다.설정 되 지 않 았 을 때 매번 다른 IP 로 요청 하 더 라 도 반 파충류 (즉, '너무 자주 조작 하 시 니 잠시 후에 다시 방문 하 십시오') 가 발생 합 니 다.실험 을 통 해 scrapy 가 쿠키 를 설정 하지 않 으 면 몇 번 의 요청 중의 쿠키 JSESSIONIDuser_trace_token 필드 가 각각 같 기 때문에 이 몇 번 의 '동일' 요청 이 반 파충류 에 의 한 것 으로 나 타 났 다.
    def parse(self,response):
        # print('first head')
        # print(response.request.headers)
        #     
        ajax_url = "https://www.lagou.com/jobs/positionAjax.json?kd={}"
        class_list=response.xpath("//a[@data-lg-tj-id='4O00']/text()").extract()
        # print('class_list : ',class_list)
        for job_class in class_list:
            print("yield:",job_class)
            yield scrapy.Request(url=ajax_url.format(job_class),cookies={'JSESSIONID':uuid.uuid4(),
                                                                         'user_trace_token':uuid.uuid4()},callback=self.parse_page,dont_filter=True,meta={'pn':1,'job_class':job_class})

5. redirect 를 처리 할 때 가끔 redirect 에 의 해 잘못된 url 로 요청 되 며, 반 파충류 전략의 하나 로 추정 된다.
[scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (302) to  from 

redirect 의 url 에 요청 하면 잘못된 페이지 를 얻 을 수 있 지만 응답 은 200 입 니 다.
[scrapy.core.engine] DEBUG: Crawled (200)  from  (referer: https://www.lagou.com/jobs/list_)

해결 방법 은 parse_page 에서 점프 후의 잘못된 페이지 를 분석 하고 있 는 지 판단 한 다음 에 점프 전의 url response.meta['redirect_urls'][0] 을 얻 고 이 url 에 다시 요청 하 는 것 입 니 다.
 def parse_page(self,response):
        ajax_url = "https://www.lagou.com/jobs/positionAjax.json?kd={}&pn={}"
        try:
            result = json.loads(response.text)["content"]["positionResult"]["result"]
        except json.decoder.JSONDecodeError as e:
            if 'redirect_urls'in response.meta:                                   # redirect     , response.meta['redirect_urls']   redirect   url,     url
                logging.info('redirect request:'+str(response.meta['redirect_urls']))
                re_url=response.meta['redirect_urls'][0]
            else:                                                                  #     ,     url
                re_url=response.url
            yield scrapy.Request(url=re_url,cookies={'JSESSIONID':uuid.uuid4(),
                                                                            'user_trace_token':uuid.uuid4()},callback=self.parse_page,dont_filter=True,meta=response.meta)
            return

6. url 의 정확성 검사 (http 인 코딩 문제)
2018-01-05 16:30:34 [scrapy.core.engine] DEBUG: Crawled (200)  (referer: https://www.lagou.com/jobs/list_)
2018-01-05 16:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.lagou.com/jobs/positionAjax.json?kd=C>

scrapy 는 기어 오 르 기 https://www.lagou.com/jobs/positionAjax.json?kd=C#&pn=8 를 표시 하지만 실제 기어 오 르 기 https://www.lagou.com/jobs/positionAjax.json?kd=C scrapy 는 # 문자 에 대해 정확 한 http 인 코딩 을 하지 않 고 https://www.lagou.com/jobs/positionAjax.json?kd=C#&pn=8 에 직접 요청 합 니 다. http 프로 토 콜 에 따라 # 의 내용 을 무시 하고 https://www.lagou.com/jobs/positionAjax.json?kd=C 에 요청 합 니 다.scrapy 에서 우 리 는 # 를 정확 한 http 인 코딩 형식, 즉 %23 으로 바 꿔 야 한다.
 count=0
        for i in class_list:
            if i=='C#':
                class_list[count]='C%23'
            count+=1

        for job_class in class_list:
            print("yield:{} url: {}".format(job_class,ajax_url.format(job_class,1)))
            logging.info("yield:{} url: {}".format(job_class,ajax_url.format(job_class,1)))
            yield scrapy.Request(url=ajax_url.format(job_class,1),cookies={'JSESSIONID':uuid.uuid4(),
                                                                         'user_trace_token':uuid.uuid4()},callback=self.parse_page,dont_filter=True,meta={'pn':1,'job_class':job_class,'max_retry_times':5})

좋은 웹페이지 즐겨찾기