2014-12-19 1 views
0

안녕하세요, 친구들과XPath/Scrap scrape DOCTYPE

저는 Scrapy와 XPath를 사용하여 스크레이퍼를 만들고 있습니다. 내가 긁어 모으는 데 관심이있는 것은 내가 가로 지르는 모든 사이트의 DOCTYPE이며 이것에 관한 문서를 찾는 데 어려움을 겪고 있으며 상대적으로 간단한 요청이기 때문에 가능해야한다고 생각합니다. 어떤 제안? ,

import scrapy 
from scrapy.selector import HtmlXPathSelector 
from scrapy.http import HtmlResponse 
from tutorial.items import DanishItem 
from scrapy.http import Request 
import csv 


class DanishSpider(scrapy.Spider): 
    name = "dmoz" 
    allowed_domains = [] 
    start_urls = [very long list of websites] 

    def parse(self, response): 
    for sel in response.xpath(???): 
     item = DanishItem() 
     item['website'] = response 
     item['DOCTYPE'] = sel.xpath('????').extract() 
     yield item 

새로운 거미 DOCTYPE을 검색하지만, 어떤 이유로 지정된 .json 내 반응을 인쇄합니다 :

건배, 여기

조이는 지금까지이 그 코드입니다 파일을 한 번만 사용하지 않고 15 번

class DanishSpider(scrapy.Spider): 
    name = "dmoz" 
    allowed_domains = [] 
    start_urls = ["http://wwww.example.com"] 

    def parse(self, response): 
    for sel in response.selector._root.getroottree().docinfo.doctype: 
     el = response.selector._root.getroottree().docinfo.doctype 
     item = DanishItem() 
     item['website'] = response 
     item['doctype'] = el 
     yield item 

답변

1

다른 접근 방식을 읽어한다면이 충분해야

response.selector._root.getroottree().docinfo.doctype 

있지만 :는 기본 선택으로 lxml를 사용,이처럼 lxml에서이 정보를 얻을 수있는 response.selector 핸들을 사용할 수 있습니다.

당신은 scrapy의 정규식 추출기를 사용하여 동일한 정보를 추출 할 수 있어야한다 :

response.selector.re("<!\s*DOCTYPE\s*(.*?)>") 

하지만, 불행하게도,이 lxml 오히려 의심 행동을했다는 사실로 인해 작동하지 않습니다 (a bug ?)을 직렬화 할 때 doctype 정보를 삭제합니다. 그렇기 때문에 selector.re에서 직접 가져올 수 없습니다.

import re 
s = re.search("<!\s*doctype\s*(.*?)>", response.body, re.IGNORECASE) 
doctype = s.group(1) if s else "" 

업데이트 :
당신은 제대로 직렬화되는 response.body 텍스트에 직접 re 모듈을 이용하여 아주 간단이 작은 장애물을 극복 할 수있는 다른 문제에 관해서는

, 그 이유는 다음과 같은. 줄 번호 :

response.selector._root.getroottree().docinfo.doctype 

string이 아닌 목록 또는 유사한 반복기를 반환하십시오. 따라서 반복 할 때 기본적으로 문자열의 문자를 반복합니다. 예를 들어 DOCTYPE이 <!DOCTYPE html> 인 경우 해당 문자열에 15자를 포함하므로 루프가 15 번 반복됩니다. 다음과 같이 확인할 수 있습니다.

for sel in response.selector._root.getroottree().docinfo.doctype: 
    print sel 

및 1 줄에 하나씩 DOCTYPE 문자열을 인쇄해야합니다.

당신이해야 할 일은 for 루프를 모두 제거하고 반복하지 않고 데이터를 가져 오는 것입니다. 또한 item['website'] = response으로 웹 사이트 URL을 수집하려는 경우 item['website'] = response.url으로 변경해야합니다. 그래서 기본적으로 :

def parse(self, response): 
    doctype = response.selector._root.getroottree().docinfo.doctype 
    item = DanishItem() 
    item['website'] = response.url 
    item['doctype'] = doctype 
    yield item 
+0

위대한 작품!내가 지금 알아낼 수없는 것만이 .json 파일에 응답을 15 번 작성하는 이유입니다. 위의 내용을 참조하십시오. –

+0

답변에서 내 업데이트를 확인하십시오. – bosnjak

+0

철저한 설명에 감사드립니다! 이것은 크게 작동합니다 :) –