Spider-scrapy의 xpath 구문 및 디버깅

18419 단어
setting의 로봇 필터를false로 설정합니다
ROBOTSTXT_OBEY = False

문법

artcile
모든 서브노드 선택하기/article
루트 요소 선택artilearticle/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

좋은 웹페이지 즐겨찾기