2017-03-14 7 views
0

나는 치료뿐만 아니라 파이썬도 처음 사용합니다. 시드 URL을 크롤링하려고 시도했습니다. https://www.health.com/patients/status/.This 시드 URL에 많은 URL이 포함되어 있습니다. .Finally 내가 원하는 ... 각 https://www.health.com/Faci/Details/2 페이지 내부웹 스크래치를 사용하여 데이터 크롤링 및 추출

https://www.health.com/patients/status/ ->https://www.health.com/Faci/Details/2                           
            -> https://www.health.com/Faci/Details/3 
            -> https://www.health.com/Faci/Details/4 



https://www.health.com/Faci/Details/2 -> https://www.health.com/provi/details/64 
           -> https://www.health.com/provi/details/65 


https://www.health.com/Faci/Details/3 -> https://www.health.com/provi/details/70 
           -> https://www.health.com/provi/details/71 

https://www.health.com/provi/details/64 https://www.health.com/provi/details/65이 :하지만 국지적 인 URL이 아래와 같이 될 것입니다 씨 URL에서 Faci/세부/#의 somenumber를 포함하는 URL 만 가져 오려는 https://www.health.com/provi/details/#somenumber url에서 데이터를 가져 오려면 어떻게해야합니까? 어떻게하면됩니까?

은 지금부터 나는 settings.py가이 일을하지 않는 file.But에 .I 깊이 제한을 설정하려고 https://www.health.com/provi/details/#somenumber로하지 않을 https://www.health.com/Faci/Details/#somenumber .Its 만 포함 URL을 크롤링 scrapy 튜토리얼과 수에서 아래의 코드를 시도 .

import scrapy 
from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors import LinkExtractor 
from news.items import NewsItem 


class MySpider(CrawlSpider): 
name = 'provdetails.com' 
allowed_domains = ['health.com'] 
start_urls = ['https://www.health.com/patients/status/'] 

rules = (

    Rule(LinkExtractor(allow=('/Faci/Details/\d+',)), follow=True), 

    Rule(LinkExtractor(allow=('/provi/details/\d+',)),callback='parse_item'),     
) 

def parse_item(self, response): 
    self.logger.info('Hi, this is an item page! %s', response.url) 
    item = NewsItem() 
    item['id'] = response.xpath("//title/text()").extract() 
    item['name'] = response.xpath("//title/text()").extract() 
    item['description'] = response.css('p.introduction::text').extract() 
    filename='details.txt' 
    with open(filename, 'wb') as f: 
     f.write(item) 
    self.log('Saved file %s' % filename) 
    return item 

더 진행 하시겠습니까?

답변

1

사실, 정규식 기반의 힘이 Rule/LinkExtractor은 종종 저에게 힘든 시간을주었습니다. 간단한 프로젝트의 경우 페이지의 모든 링크를 추출한 다음 href 속성을 살펴 보는 것이 좋습니다. href가 필요에 맞는 경우 yieldResponse 개체가 필요합니다. 코드에

from scrapy.http import Request 
from scrapy.selector import Selector 
... 
    # follow links 
    for href in sel.xpath('//div[@class="contentLeft"]//div[@class="pageNavigation nobr"]//a').extract(): 
      linktext = Selector(text=href).xpath('//a/text()').extract_first() 
      if linktext and linktext[0] == "Weiter": 
        link = Selector(text=href).xpath('//a/@href').extract()[0] 
        url = response.urljoin(link) 
        print url 
        yield Request(url, callback=self.parse) 

일부 발언 : 예를 들어

response.xpath(...).extract() 

이 목록을 반환합니다, 어쩌면 당신은 첫 번째 항목을 제공 extract_first() (또는 None)에 모습을 갖고 싶어.

with open(filename, 'wb') as f: 

이렇게하면 파일을 여러 번 덮어 씁니다. 마지막으로 저장된 항목 만 얻을 수 있습니다. 또한 이진 모드 ('b')로 파일을 엽니 다. 파일 이름에서 텍스트로 읽고 싶습니까? 추가하려면 'a'을 사용 하시겠습니까? open() docs 을 참조하십시오. 대안으로 scrapys 기능을 사용하여 항목을 JSON 또는 CSV에 저장하는 경우 -o flag을 사용하는 것입니다.

return item 

yield 항목을 반환하는 대신 좋은 스타일입니다. 적어도 한 페이지에서 여러 항목을 작성해야한다면 yield이 필요합니다.

다른 좋은 접근법은 다음과 같습니다. 한 유형/종류의 페이지에 대해 하나의 parse() 함수를 사용하십시오.

예를 들어 start_urls의 모든 페이지는 모두 parse()으로 끝납니다. 그걸 추출하면 각 /Faci/Details/N 페이지에 대해 yieldRequest을 콜백 parse_faci_details()과 함께 추출 할 수 있습니다. parse_faci_details()에서 관심있는 링크를 다시 추출한 다음 Request 초를 만들고 callback=을 통해이를 전달합니다. parse_provi_details(). 이 함수에서는 필요한 항목을 만듭니다.