2017-10-17 3 views
0

저는 Python과 Scrapy에 새로 도입되었지만 중첩 된 html 요소를 반복 할 때 원하는 결과를 얻지 못했습니다.Scrapy : 중첩 된 항목을 반복하지만 원하는 출력을 생성하려고하지 않습니다.

아래 HTML은 스크랩하려고합니다.

<div class="level1" role="main"> 
<div class="level2"> 
    <h1 id="fullStoreHeading" class="class_h1">Page Title</h1> 
    <div class="fsdColumn_3"> 
     <div class='fsdDeptBox'> 
      <img alt="" src="" aria-hidden="true" height="100%" width="100%"> 
      <h2 class="fsdDeptTitle">TV</h2> 
      <div class='fsdDeptCol'> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1001">Samsung</a> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1002">Vizio</a> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1003">Element</a> 
      </div> 
     </div> 
     <div class='fsdDeptBox'> 
      <img alt="" src="" aria-hidden="true" height="100%" width="100%"> 
      <h2 class="fsdDeptTitle">Laptop</h2> 
      <div class='fsdDeptCol'> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1004">Apple</a> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1005">Microsoft</a> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1006">Dell</a> 
      </div> 
     </div> 
    </div> 


    <div class="fsdColumn_3"> 
     <div class='fsdDeptBox'> 
      <img alt="" src="" aria-hidden="true" height="100%" width="100%"> 
      <h2 class="fsdDeptTitle">Video Game Console</h2> 
      <div class='fsdDeptCol'> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1007">Xbox One</a> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1008">Xbox 360</a> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1009">PS 5</a> 
      </div> 
     </div> 
     <div class='fsdDeptBox'> 
      <img alt="" src="" aria-hidden="true" height="100%" width="100%"> 
      <h2 class="fsdDeptTitle">SSD</h2> 
      <div class='fsdDeptCol'> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1010">Samsung Evo</a> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1011">Crucial</a> 
       <a class="class_a" href="/test?_encoding=UTF8&id=1012">Sandisk</a> 
      </div> 
     </div> 
    </div> 
</div> 

나는 위의 HTML에서 생성하기 위해 노력하고 출력은 목록입니다 : -> 브랜드 -

제품 카테고리> 이드

일예

TV

Samsung 1001 

    Vizio 1002 

    Element 1003 

노트북

Apple 1004 

    Microsoft 1005 

    Dell 1006 

비디오 게임 콘솔

Xbox Onen 1007 

    Xbox 360 1008 

    PS4 1009 

ProductCategories.py

def parse(self, response): 
    l = ItemLoader(item=ProductSpiderItem(), response=response) 

    titles = response.xpath('//*[@class="fsdDeptTitle"]') 

    for title in titles: 

     Product_Category= title.xpath('text()').extract() 

     l.add_value('Product_Category', Product_Category) 

     for brnd in 
      title.xpath('//*[@class="fsdDeptCol"]/a[@class="class_a"]'): 

       Brand = brnd.xpath('text()').extract() 
       l.add_value('Brand', Brand) 

    return l.load_item() 

현재 "Outer For Loop"의 모든 제품 범주를 한 번 인쇄하고 "Inner For Loop"는 제품 범주와 상관없이 모든 브랜드를 인쇄하고 "Inner For Loop"는 " Outer For Loop "가 실행됩니다.

문제를 해결하는 데 도움을 주시면 감사하겠습니다.

고마워요.

답변

1

첫 번째 'for'루프는 HTML의 <h2 class="fsdDeptTitle">SSD</h2> 부분을 반복하여 전송합니다. 그런 다음 코드에서 class=class_a을 찾으십시오. 첫 번째 'for'루프가 너무 명확하여 'class_a'가 HTML을 선택하기 때문에 그렇게 할 수 없습니다.

'for'루프를 HTML에서 한 단계 더 높게 표시하여이를 해결할 수 있습니다.

titles = response.xpath("//*[@class='fsdDeptBox']") 
for title in titles: 
    Product_Category=title.xpath('text()').extract() 
    l.add_value('Product_Category', Product_Category) 

    for brnd in title.xpath('div[@class="fsdDeptCol"]'): 
     Brand = brnd.xpath('*/text()').extract() 
     l.add_value('Brand', Brand) 
    return l.Load_item() 

나는 'for'루프 첫 번째는 'class_a'텍스트

사이드 노트에 대한 경로를 포함하도록 HTML의 정도를 선택하도록 변경. 올바른 HTML 용어에 대해 많이 알지 못하지만 여전히 의미가 있기를 바랍니다.

+0

미안, 내가 깜빡 이 게시물을 쓰는 동안 *를 쓰십시오. 나는 그 지위를 편집했다. 당신의 제안에 따라, 나는 * [@ class = "fsdDeptCol"]/a [@ class = "class_a"] '... 그러나 브랜드에 대한 레코드를 반환하지 않습니다. – Raj

+0

나는이 질문에 더 잘 대답하기 위해 나의 대답을 편집했다.내 컴퓨터에 파일로 주어진 HTML을 저장하고 scrapy shell로 열었다. 나는 원하는 출력을 얻을 수있었습니다. – SuperStickman22

+0

예. 이제 작동 중입니다. 많이 감상 할 수 있습니다! – Raj

1

조금 더 확인해야한다고 생각합니다. ItemLoader.

다음
class ProductItem(Item): 
    category = Field() 
    brand = Field() 
class ProductItemLoader(ItemLoader): 
    default_item_class = ProductItem 
    default_output_processor = TakeFirst() 

이 같은 것을 할 수있는 : 그들은 또한의 당신이 다음과 같이 정의했다고 가정하자 예를 들어, 항목 및 항목 로더가 정의하는 방법에 따라

for product in response.css('.fsdDeptCol a'): 
    il = ProductItemLoader(selector=product) 
    il.add_xpath('category', './ancestor::*/preceding-sibling::h2/text()') 
    il.add_xpath('brand', './text()') 
    yield il.load_item() 
+0

고맙습니다 ... href 값에서 "id"를 추출하는 가장 좋은 방법이 있습니까? href 값에서 전체 문자열을 추출 할 수있었습니다. – Raj

+1

여러분이'id' 필드 (그리고 w3lib와 scrap의 프로세서에서 가져온 올바른 값)가'il.add_xpath ('id', './href', MapCompose (lambda : url_query_parameter x, 'id')))' – Wilfredo

+0

다시 한번 감사드립니다. 내가 다른 표를 줄 수 있으면 좋겠어. 나에게 MapCompose 등등과 같은 진보적 인 기술을 배울 수있는 좋은 기사 나 책을 나에게 추천 해 줄 수 있었 을까? – Raj