Spider-scrapy의 xpath 구문 및 디버깅
ROBOTSTXT_OBEY = False
문법
artcile
모든 서브노드 선택하기
/article
루트 요소 선택artile
article/a
artile에 속하는 모든 하위 요소 중 a 요소를 선택하십시오
//div
문서에 나타나는 위치에 관계없이 모든 div 요소를 선택합니다.
article//div
article 아래에 나타나는 위치에 상관없이artile 요소의 후손에 속하는div 요소를 선택하십시오
//@class
class라는 모든 속성을 선택하십시오.
/article/div[1]
article 하위 요소에 속하는 첫 번째 div 요소 선택하기
/article/div[last()]
article 하위 요소에 속하는 마지막 div 요소를 선택합니다.
/article/div[last()-1]
article 하위 요소에 속하는 밑에서 두 번째div 요소를 선택합니다.
//div[@lang]
lang 속성을 가진div 요소를 모두 선택하십시오
//div[@lang='eng']
모든 lang 속성이 eng인 div 요소를 선택하십시오
debug
1 pycharm
id는 전역에서 유일합니다
re_selector2 = response.xpath('//*[@id="post-110595"]/div[1]/h1/text()')
class='entry-header'
가 전역에서 유일하면 위쪽보다 노드를 줄일 수 있습니다.re_selector3 = response.xpath("//div[@class='entry-header']/h1/text()")
2 scrapy shell
페이지
http://blog.jobbole.com/110595/
에 debug 수행scrapy shell http://blog.jobbole.com/110595/
response 대상을 얻다.
dir(response)
로 속성과 방법을 볼 수 있습니다.타입을 type(response)
로 보다.>>> title = response.xpath("//div[@class='entry-header']/h1/text()")
>>> title
["//div[@class='entry-header']/h1/text()" data=' ? 20 '>]
타이틀의 데이터를 어떻게 얻습니까?
extract()
방법을 사용하여 수조를 얻어 번호로 구체적인 값을 얻을 수 있다.>>> title.extract()
[' ? 20 ']
>>> title.extract()[0]
' ? 20 '
extra () 를 직접 사용하지 않는 것은 타이틀이 selector 대상으로 유지될 수 있기 때문입니다.
시간을 얻으려면 안에 있는 텍스트를
text()
로 가져오십시오.다시 strip()
기본값으로 기본 문자를 내보냅니다.>>> create_date = response.xpath("//p[@class='entry-meta-hide-on-mobile']/text()").extract()[0]
>>> create_date
'\r
\r
2017/03/18 · '
>>> create_date = create_date.strip()
>>> create_date
'2017/03/18 ·'
>>> a = create_date.replace("·","").strip()
>>> a
'2017/03/18'
>>> b = create_date.strip("·")
>>> b
'2017/03/18 '
>>> b = create_date.strip("·").strip()
>>> b
'2017/03/18'
xpath의 함수인contains를 사용하여 여러 개의class 속성 중 하나만 가져옵니다.
예를 들어
span
를 선택하려면class가 여러 개 있습니다.그중vote-post-up
만 원하면 xpath의contains를 사용할 수 있습니다."110595" class=" btn-bluet-bigger href-style vote-post-up register-user-only ">class="fa fa-thumbs-o-up"> "110595votetotal">2
>>> response.xpath("//span[contains(@class, 'vote-post-up')]")
["//span[contains(@class, 'vote-post-up')]" data=''>]
목록 생성
리뷰 필터링
>>> response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()[0:]
[' ', ' 7 ', ' ']
>>> [element for element in tag_list if not element.strip().endswith(" ")]
[' ', ' ']
tag_list = [ element for element in tag_list if not element.strip().endswith(" ") ]
tags = ",".join(tag_list)
어떤 결말로 끝나는지는 틀림없다
.endswith()
extract_first()
수조에서 0번째, 1번을 찾았을 때 수조가 비어 있으면 이상을 던질 수 있습니다.
그러나
extract_first()
를 사용하면 이상 처리를 하지 않아도 된다. 결과는 비어 있거나 None이다.def extract_first(self, default=None):
for x in self:
return x.extract()
else:
return default
사전과 같은 get 방법으로 추출하지 못하면 비어 있습니다.
결국jobbole.py
# -*- coding: utf-8 -*-
import re
import scrapy
class JobboleSpider(scrapy.Spider):
name = "jobbole"
allowed_domains = ["blog.jobbole.com"]
start_urls = ['http://blog.jobbole.com/110595/']
def parse(self, response):
# re_selector1 = response.xpath("/html/body/div[1]/div[3]/div[1]/div[1]/h1")
# re_selector2 = response.xpath('//*[@id="post-110595"]/div[1]/h1/text()')
# re_selector3 = response.xpath("//div[@class='entry-header']/h1/text()")
title = response.xpath("//div[@class='entry-header']/h1/text()").extract()[0]
create_date = response.xpath("//p[@class='entry-meta-hide-on-mobile']/text()").extract()[0].strip().replace("·","").strip()
praise_nums = response.xpath("//span[contains(@class, 'vote-post-up')]//h10/text()").extract()[0]
fav_nums = response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0]
match_re = re.match(".*?(\d+).*", fav_nums)
if match_re:
fav_nums = match_re.group(1)
comment_nums = response.xpath("//a[@href='#article-comment']/span/text()").extract()[0]
match_re = re.match(".*?(\d+).*", comment_nums)
if match_re:
comment_nums = match_re.group(1)
content = response.xpath("//div[@class='entry']").extract()[0]
tag_list = response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()
tag_list = [ element for element in tag_list if not element.strip().endswith(" ") ]
tags = ",".join(tag_list)
# css
title = response.css(".entry-header h1::text").extract()[0]
create_date = response.css(".entry-meta-hide-on-mobile::text").extract()[0].strip().replace("·","").strip()
praise_nums = response.css("div.post-adds h10::text").extract()[0]
# fav_nums = response.css("span[class*='bookmark-btn']::text").extract()[0]
fav_nums = response.css(".bookmark-btn::text").extract()[0]
match_re = re.match(".*?(\d+).*", fav_nums)
if match_re:
fav_nums = match_re.group(1)
# comment_nums = response.css("span[class='btn-bluet-bigger href-style hide-on-480']::text").extract()[0]
comment_nums = response.css("a[href='#article-comment'] span::text").extract_first()
match_re = re.match(".*?(\d+).*", comment_nums)
if match_re:
comment_nums = match_re.group(1)
content = response.css(".entry").extract()[0]
tag_list = response.css("p.entry-meta-hide-on-mobile a::text").extract()
tag_list = [element for element in tag_list if not element.strip().endswith(" ")]
tags = ",".join(tag_list)
pass
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.