Python 파충류 실례--scrapy 프레임 워 크

본 고의 실례 는 인터넷 의 python 관련 직위 정 보 를 추출 하 는 것 이다.이런 정 보 는 직위 상세 페이지,예 를 들 어 직위 명,임금,회사 명 등 이다.
사고 방향 을 분석 하 다.
분석 조회 결과 페이지
체크 망 검색 상자 에서'python'키 워드 를 검색 하면 브 라 우 저 주소 표시 줄 에서 검색 결과 페이지 의 url 을 볼 수 있 습 니 다.'https://www.lagou.com/jobs/list_python?labelWords=&from Search=true&suginput=',시도 해 보 시 겠 습 니까?뒤의 매개 변 수 를 삭제 하 였 는데,접근 결과 가 같 음 을 발견 하 였 습 니 다.
Chrome 웹 페이지 디 버 깅 도구(F12)를 열 고 모든 검색 결과(즉,모든 직위)가 html 에 있 는 요소 의 포 지 셔 닝 을 분석 한 결과 모든 결과 가
    아래 li 태그 에서...

    각 직위 의 구체 적 인 정보 가 필요 하기 때문에 모든 검색 결과 의 상세 한 url,즉 검색 결 과 를 클릭 한 후 들 어 가 는 상세 한 페이지 의 url 을 가 져 와 야 합 니 다.
    li 태그 의 요 소 를 계속 보고 원 하 는 상세 한 url 을 찾 습 니 다.찾 은 url 은:href=입 니 다.https://www.lagou.com/jobs/6945237.html?show=b6e8e778fcae4c2aa2111ba58f9ebfa0

    다른 검색 결과 에 대한 자세 한 정 보 를 보 니 url 형식 이 모두 href="입 니 다.https://www.lagou.com/jobs/{어떤 id}.html?show={showid}" rel="external nofollow"
    첫 번 째 ID 에 대해 서 는 결과 마다 id 가 다 릅 니 다.각 직위 를 표시 하 는 유일한 id 라 고 생각 합 니 다.showid,모든 결과 의 id 는 같 습 니 다.show 파 라 메 터 를 삭제 하려 고 시도 하 였 으 며,구체 적 인 결과 상세 페이지 에 접근 할 수 있 음 을 발견 하 였 습 니 다.
    그러면 저 희 는 xpath 를 통 해 모든 직위 의 첫 번 째 ID 를 직접 추출 하면 됩 니 다.그러나 디 버 깅 도구 의 elements 태그 에 있 는 html 는 최종 웹 페이지 에 보 여 주 는 html 입 니 다.꼭 저희 가 방문 하 는 것 은 아 닙 니 다.https://www.lagou.com/jobs/list_python 에서 돌아 온 response 의 html 이 므 로 Network 탭 을 누 르 고 페이지 를 다시 새로 고침 하여 찾 습 니 다.https://www.lagou.com/jobs/list_python 에 대응 하 는 요청 입 니 다.대응 하 는 response 를 보고'position'을 검색 하 십시오.링크'(즉,앞에서 우리 가 elements 에서 찾 은 모든 검색 결과 에 대한 상세 한 정보 url)는 하나의 사이트 주 소 를 되 돌려 준 것 을 발견 했다.그러나 중요 한 두 개의 ID 는 직접 돌려 보 낸 것 이 아니 라 js 를 통 해 생 성 된 것 으로 우리 가 원 하 는 구체 적 인 데 이 터 는 이것 이 아니 라 되 돌려 주 십시오.

    그러면 우 리 는 구체 적 으로 그 요청 이 검색 결 과 를 되 돌려 주 는 정 보 를 찾 아야 합 니 다.일반적으로 이러한 상황 에서 ajax 를 통 해 얻 은 데이터 인지 아 닌 지 를 먼저 고려 하고 유형 이 XHR(ajax)인 요청 을 선별 하여 response 를 하나씩 볼 수 있 습 니 다.positionAjax.json 이 되 돌아 오 는 데이터 에는 우리 가 원 하 는 모든 검색 결과 에 대한 정보 가 존재 합 니 다.이것 은 확실히 ajax 를 통 해 얻 은 데이터 임 을 설명 합 니 다.사실 다음 페이지 를 클릭 하면 주소 표시 줄 url 주소 가 변 하지 않 았 고 부분 적 으로 검색 결과 의 데 이 터 를 새로 고 쳤 을 뿐 검색 결 과 를 ajax 를 통 해 되 돌 아 왔 음 을 알 수 있 습 니 다.

    위의 ajax response 를 분석 하고 그 중에서 우리 가 원 하 는 직위 ID 가 있 는 지 확인 합 니 다.preview 에서 검색 하기 전에 elements 에서 찾 은 특정한 직위 의 url 의 두 ID 는 response 에 존재 합 니 다.첫 번 째 ID 는 positionId 이 고 두 번 째 는 showId 입 니 다.response 에서 현재 페이지 번호 pageno 로 돌아 간 것 도 발견 할 수 있 습 니 다.
    따라서 우 리 는 위 ajax 에 대응 하 는 url 만 방문 해 야 합 니 다:https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false 우리 가 원 하 는 ID 를 받 아서 상세 한 url 템 플 릿 을 채 울 수 있 습 니 다.https://www.lagou.com/jobs/{position_id}.html?show={show_id}에서 자세 한 페이지 를 방문 할 수 있 습 니 다.
    하지만 우리 가 직접 방문 하면https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false 시,돌아 온 결 과 는:  {"status":false,"msg":"작업 이 너무 잦 습 니 다.잠시 후에 다시 방문 하 십시오.","clientIp":"139.226.66.44","state":2402}

    바 이 두 의 조 회 를 통 해 원래 상술 한 주 소 를 직접 방문 하면 안 된다 는 것 을 알 게 되 었 습 니 다.이것 도 갈고리 의 역 기어 오 르 기 전략 입 니 다.전에 조회 결과 페이지 를 가 져 가 야 합 니 다(https://www.lagou.com/jobs/list_python?)쿠키 를 사용 해 야 합 니 다.scrapy 프레임 워 크 를 사용 하고 있 기 때문에 이 프레임 워 크 는 지난번 에 요청 한 쿠키 를 가지 고 다음 요청 에 접근 할 수 있 습 니 다.따라서 쿠키 정 보 를 수 동 으로 추가 할 필요 가 없습니다.검색 결과 페이지 를 먼저 방문 하면 됩 니 다.즉,starturl = https://www.lagou.com/jobs/list_python
    또한 이 ajax 요청 은 POST 방식 으로 보 내 졌 기 때문에 제출 한 form 데 이 터 를 분석 해 야 합 니 다.첫 페이지 에 세 개의 데이터 정보 가 있 습 니 다.first 는 true 이 고 pn 은 1kd 는 python 이 며 두 번 째 페이지 에 first 는 false 이 고 pn 은 2 이 며 kd 역시 python 이 며 sid 가 하나 더 있 습 니 다.
    이 네 개의 매개 변 수 를 분석 하면 첫 번 째 first 는 첫 번 째 페이지 인지 아 닌 지 를 나타 내 는 것 이 고 두 번 째 pn 은 현재 페이지 수 를 나타 내 는 것 이 며 세 번 째 kd 는 검색 을 나타 내 는 키 워드 를 나타 내 는 것 이다.네 번 째 sid 는 위의 showId 와 비교 한 결과 그 값 이 showId 인 것 을 발견 했다.

    분석 직위 상세 페이지
    앞에서 분석 한 후에 직무 상세 페이지 url 을 연결 할 수 있 습 니 다.상세 페이지 를 클릭 하고 똑 같은 사고 로 우리 가 원 하 는 데이터 가 상세 페이지 의 url 에 있 는 지 분석 할 수 있 습 니 다.여기 서 직무 명칭,월급,장소,경험,키워드,회사 정보 등 을 원 합 니 다.

    network 에서 대응 하 는 response 를 찾 으 면 데이터 가 response 에 존재 하 는 것 을 발견 하여 xpath 를 통 해 원 하 는 데 이 터 를 추출 할 수 있 습 니 다.
    파충류 코드 작성
    구체 적 인 코드 는 github 에 있 습 니 다.
    여기 키 코드 만 나 와 요.
    scrapy 프로젝트 만 들 기
    
    scrapy startproject LaGou
    파충 류 를 만들다
    
    scrapy genspider lagou www.lagou.com
    items.py 를 작성 하여 기어 오 르 려 는 필드 를 설정 합 니 다.
    
    # -*- coding: utf-8 -*-
    
    # Define here the models for your scraped items
    #
    # See documentation in:
    # https://docs.scrapy.org/en/latest/topics/items.html
    
    import scrapy
    
    
    class LagouItem(scrapy.Item):
     # define the fields for your item here like:
     job_url = scrapy.Field()
     job_name = scrapy.Field()
     salary = scrapy.Field()
     city = scrapy.Field()
     area = scrapy.Field()
     experience = scrapy.Field()
     education = scrapy.Field()
     labels = scrapy.Field()
     publish_date = scrapy.Field()
     company = scrapy.Field()
     company_feature = scrapy.Field()
     company_public = scrapy.Field()
     company_size= scrapy.Field()
    파충류 코드 작성 lagou.py
    
    # -*- coding: utf-8 -*-
    import scrapy
    from LaGou.items import LagouItem
    import json
    from pprint import pprint
    import time
    
    
    class LagouSpider(scrapy.Spider):
     name = 'lagou'
     allowed_domains = ['www.lagou.com']
     start_urls = ['https://www.lagou.com/jobs/list_python?']
    
     def __init__(self):
      #      ,       ,                         
      self.headers = {
       "Accept": "application/json, text/javascript, */*; q=0.01",
       "Connection": "keep-alive",
       "Host": "www.lagou.com",
       "Referer": 'https://www.lagou.com/jobs/list_Python?',
       "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
       "referer": "https://www.lagou.com/jobs/list_python?"
      }
      self.sid = ''
      self.job_url_temp = 'https://www.lagou.com/jobs/{}.html?show={}'
      #     
      with open('jobs.json', 'w') as f:
       f.truncate()
    
     def parse(self, response):
      """
           
      """
      # response GET      ,     cookie
      #   POST       cookies,          
      yield scrapy.FormRequest(
       'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false',
       callback=self.parse_list,
       formdata={"first": "false",
          "pn": "1",
          "kd": "python",
          },
       headers=self.headers
      )
     def parse_list(self, response):
      """
              json  
      """
      #      json,    
      res_dict = json.loads(response.text)
      #         
      if not res_dict.get('success'):
       print(res_dict.get('msg', '    '))
      else:
       #       
       page_num = res_dict['content']['pageNo']
       print('     {} '.format(page_num))
       #   sid
       if not self.sid:
        self.sid = res_dict['content']['showId']
       #         url  
       part_url_dict = res_dict['content']['hrInfoMap']
       #       
       for key in part_url_dict:
        #         item
        item = LagouItem()
        #       url
        item['job_url'] = self.job_url_temp.format(key, self.sid)
        #        
        yield scrapy.Request(
         item['job_url'],
         callback=self.parse_detail,
         headers=self.headers,
         meta={'item': item}
        )
    
       #      
       if page_num < 30:
        # time.sleep(2)
        yield scrapy.FormRequest(
         'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false',
         callback=self.parse_list,
         formdata={"first": "false",
            "pn": str(page_num+1),
            "kd": "python",
            "sid": self.sid
            },
         headers=self.headers
        )
    
     def parse_detail(self, response):
      """
             
      """
      #   item
      item = response.meta['item']
      #     
      #      div
      job_div = response.xpath('//div[@class="position-content-l"]')
      if job_div:
       item['job_name'] = job_div.xpath('./div/h1/text()').extract_first()
       item['salary'] = job_div.xpath('./dd/h3/span[1]/text()').extract_first().strip()
       item['city'] = job_div.xpath('./dd/h3/span[2]/text()').extract_first().strip('/').strip()
       item['area'] = response.xpath('//div[@class="work_addr"]/a[2]/text()').extract_first()
       item['experience'] = job_div.xpath('./dd/h3/span[3]/text()').extract_first().strip('/').strip()
       item['education'] = job_div.xpath('./dd/h3/span[4]/text()').extract_first().strip('/').strip()
       item['labels'] = response.xpath('//ul[@class="position-label clearfix"]/li/text()').extract()
       item['publish_date'] = response.xpath('//p[@class="publish_time"]/text()').extract_first()
       item['publish_date'] = item['publish_date'].split('&')[0]
       #     dl
       company_div = response.xpath('//dl[@class="job_company"]')
       item['company'] = company_div.xpath('./dt/a/img/@alt').extract_first()
       item['company_feature'] = company_div.xpath('./dd//li[1]/h4[@class="c_feature_name"]/text()').extract_first()
       item['company_feature'] = item['company_feature'].split(',')
       item['company_public'] = company_div.xpath('./dd//li[2]/h4[@class="c_feature_name"]/text()').extract_first()
       item['company_size'] = company_div.xpath('./dd//li[4]/h4[@class="c_feature_name"]/text()').extract_first()
       yield item
    middlewares.py 를 작성 하여 요청 을 보 내기 전에 user-agent 를 무 작위 로 설정 합 니 다.여 기 는 제3자 라 이브 러 리 fake 를 사용 합 니 다.useragent,user-agent 를 무 작위 로 제공 할 수 있 습 니 다.사용 하기 전에 설치:pip install fakeuseragent
    
    from fake_useragent import UserAgent
    import random
    
    class RandomUserAgentDM:
     """
         userAgent
     """
     def __init__(self):
      self.user_agent = UserAgent()
    
     def process_request(self, request, spider):
      request.headers['User-Agent'] = self.user_agent.random
    pipelines.py 를 작성 하여 데 이 터 를 json 파일 로 저장 합 니 다.
    
    import json
    
    class LagouPipeline:
     def process_item(self, item, spider):
      with open('jobs.json', 'a', encoding='utf-8') as f:
       item_json = json.dumps(dict(item), ensure_ascii=False, indent=2)
       f.write(item_json)
       f.write('
    ')
    settings.py 작성
    
    #       
    LOG_LEVEL = 'WARNING'
    
    #   ROBOTSTXT  ,   true       
    ROBOTSTXT_OBEY = False
    
    #        ,         
    DOWNLOAD_DELAY = 0.25
    
    #   DOWNLOADER_MIDDLEWARES
    DOWNLOADER_MIDDLEWARES = {
     # 'LaGou.middlewares.LagouDownloaderMiddleware': 543,
     'LaGou.middlewares.RandomUserAgentDM' :100,
    }
    
    #   ITEM_PIPELINES
    ITEM_PIPELINES = {
     'LaGou.pipelines.LagouPipeline': 300,
    }
    파충 류 를 시동 하 다
    scrapy crawl lagou
    아직도 56 페이지 밖 에 안 되 는 것 을 발견 한 것 은 그물 을 당 기 는 반 기어 오 르 기 가 확실히 잘 되 었 고 대 리 를 통 해 반 기어 오 르 기 를 계속 할 수 있다 는 것 을 의미한다.여 기 는 더 이상 시범 을 보이 지 않 는 다.

    기어 오 르 기 결과 보기

    이상 은 파 이 썬 파충류 사례-scrapy 프레임 워 크 에서 라 그 망 채용 정보 에 대한 상세 한 내용 입 니 다.파 이 썬 파충류 가 채용 정 보 를 얻 는 것 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기