페이징 상호 작용에는 데이터를 요청할 때 동기식과 비동기식의 두 가지 상황이 있습니다. 동기식의 경우 페이지가 전체적으로 새로 고쳐지고, 비동기식의 경우 페이지가 부분적으로 새로 고쳐집니다. 페이지를 매긴 두 가지 유형의 데이터는 크롤링 시 서로 다르게 처리됩니다. DEMO는 학습 전용이며 모든 도메인 이름은 테스트로 익명화됩니다
동기화된 페이징
동기화된 페이징 시 페이지가 전체적으로 새로 고쳐지고 URL 주소 표시줄이 변경됩니다
크롤러가 파싱한 데이터 객체는 html입니다
테스트 시나리오: 채용 웹사이트 베이징 지역에서 Java 채용 정보 확보
#coding=utf-8import scrapyclass TestSpider(scrapy.Spider): name='test' download_delay=3 user_agent='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36' page_url = 'http://www.test.com/zhaopin/Java/{0}/?filterOption=2' page=1 #执行入口 def start_requests(self): #第一页 yield scrapy.Request(self.page_url.format('1'), headers={'User-Agent':self.user_agent}, callback=self.parse, errback=self.errback_httpbin) #解析返回的数据 def parse(self,response): for li in response.xpath('//*[@id="s_position_list"]/ul/li'): yield{ 'company':li.xpath('@data-company').extract(), 'salary':li.xpath('@data-salary').extract() } #是否是最后一页,根据下一页的按钮css样式判断 if response.css('a.page_no.pager_next_disabled'): print('---is the last page,stop!---') pass else: self.page=self.page+1 #抓取下一页 yield scrapy.Request(self.page_url.format(str(self.page)), headers={'User-Agent':self.user_agent}, callback=self.parse, errback=self.errback_httpbin) #异常处理 def errback_httpbin(self,failure): if failure.check(HttpError): response = failure.value.response print 'HttpError on {0}'.format(response.url) elif failure.check(DNSLookupError): request = failure.request print'DNSLookupError on {0}'.format(request.url) elif failure.check(TimeoutError, TCPTimedOutError): request = failure.request print'TimeoutError on {0}'.format(request.url)
크롤러 시작: scrapy runspider //spiders //test_spider.py -o test.csv는 완료 후 생성됩니다. csv 형식의 파일:
비동기 페이징
비동기 페이징 중에 페이지는 부분적으로 새로고침해도 URL 주소 표시줄이 변경되지 않음
크롤러 분석 데이터 개체는 일반적으로 Json입니다
테스트 시나리오: 영화 웹사이트의 상위 100개 고전 영화를 크롤링
#coding=utf-8import scrapyimport jsonclass TestSpider(scrapy.Spider): name ='test' download_delay = 3 user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36' pre_url = 'https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%BB%8F%E5%85%B8&sort=recommend&page_limit=20&page_start=' page=0 cnt=0 def start_requests(self): url= self.pre_url+str(0*20) yield scrapy.Request(url,headers={'User-Agent':self.user_agent},callback=self.parse) def parse(self,response): if response.body: # json字符串转换成Python对象 python_obj=json.loads(response.body) subjects=python_obj['subjects'] if len(subjects)>0: for sub in subjects: self.cnt=self.cnt+1 yield { 'title':sub["title"], 'rate':sub["rate"] } if self.cnt<100: print 'next page-------' self.page=self.page+1 url= self.pre_url+str(self.page*20) yield scrapy.Request(url,headers={'User-Agent':self.user_agent},callback=self.parse)
크롤러 시작: scrapy runspider //spiders//test_spider.py -o test .json이 완료된 후 json 형식 파일이 생성됩니다.
Scrapy 및 BeautifulSoup 또는 lxml
Scrapy는 크롤러 작성 및 데이터 크롤링을 위한 완전한 프레임워크이고 BeautifulSoup 또는 lxml은 html/xml 구문 분석을 위한 라이브러리일 뿐이며 그 기능은 scrapy의 xpath 및 CSS 선택기와 유사합니다. scrapy에서도 사용할 수 있지만 운영 효율성은 상대적으로 낮습니다. scrapy의 선택기를 사용할 때 브라우저의 F12 모드를 사용하여 모든 노드의 xpath 및 css 값을 직접 복사할 수 있습니다.