Python 파충류 실례--scrapy 프레임 워 크
사고 방향 을 분석 하 다.
분석 조회 결과 페이지
체크 망 검색 상자 에서'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 프레임 워 크 에서 라 그 망 채용 정보 에 대한 상세 한 내용 입 니 다.파 이 썬 파충류 가 채용 정 보 를 얻 는 것 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Python의 None과 NULL의 차이점 상세 정보그래서 대상 = 속성 + 방법 (사실 방법도 하나의 속성, 데이터 속성과 구별되는 호출 가능한 속성 같은 속성과 방법을 가진 대상을 클래스, 즉 Classl로 분류할 수 있다.클래스는 하나의 청사진과 같아서 하나의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.