2017-12-19 11 views
1

내 문제는 answer과 관련이 있습니다.BeautifulSoup 여러 번 선택 사용

나는 다음과 같은 코드를 가지고 :

import urllib.request 
from bs4 import BeautifulSoup 

time = 0 

html = urllib.request.urlopen("https://www.kramerav.com/de/Product/VM-2N").read() 
html2 = urllib.request.urlopen("https://www.kramerav.com/de/Product/SDIA-IN2-F16").read() 
try: 
    div = str(BeautifulSoup(html).select("div.large-image")[0]) 
    if(str(BeautifulSoup(html).select("div.large-image")[1]) != ""): 
     div += str(BeautifulSoup(html).select("div.large-image")[1]) 
    time = time + 1 
except IndexError: 
    div = "" 
    time = time + 1 
finally: 
    print(str(time) + div) 

변수 HTML의 사이트가 "큰 이미지"라는 이름이 DIV-클래스가 있습니다. 변수 html2의 사이트에는 1이 있습니다. html로 프로그램은 의도 한대로 작동합니다. 하지만 html2로 전환하면 변수 div가 완전히 비어있게됩니다.

아무 것도 저장하지 않고 1 div 클래스를 저장하고 싶습니다. 내가 어떻게이 일을 성취 할 수 있니?

+0

예상되는 결과는 무엇입니까? 한 번에 두 페이지에서 모든 이미지를 사용할 수 있습니까? – SIM

답변

1

변수 div가 완전히 비어 있습니다.

오류 처리기가 빈 문자열을 할당했기 때문입니다.

그런 식으로 첨자, 조건문 및 처리기를 사용하지 마십시오. select()의 결과를 for으로 반복하여 결과 목록 (또는 문자열)을 만드는 것이 더 자연 스럽습니다.

또한 잠재적으로 긴 웹 페이지를 신중하게 구문 분석하므로 상당히 비싼 작업 일 수 있으므로 soup = BeautifulSoup(html)을 한 번만 만들어야합니다. 그것으로, 당신이 HTML 조각의 목록을 만들 수있다 : 어떤 이유로 당신이하지 좋아 지능형리스트라면

images = [image 
       for image in soup.select('div.large-image')] 

또는

, 당신은 동등하게 작성할 수 얻을 다음

images = [] 
    for image in soup.select('div.large-image'): 
     images.append(image) 

을하고, 필요한 html은 div = '\n'.join(images)입니다.

+0

답변 감사합니다. 나는 그것을'select = BeautifulSoup (html) .select ("div.large-image")'로 줄였다. 이제 select [index]를 사용할 수 있습니다. 그러나 for-loop는 어떻게 사용합니까? 'for for select [i] :'내 추측이 겠지만 거기서부터 어떻게해야할지 모르겠다. – dun

+2

@dun 당신은'선택의 항목'을 의미합니까? 'select'는리스트이므로 다른리스트처럼 사용하십시오. – furas

+0

네, 그런 의미였습니다. 미안하지만, 프로그래밍 기술이 꽤 낮습니다. 'for for i select : div = str (i)'를 사용할 때 두 번째 div 만 String div에 저장합니다. 어떻게 둘 다 구할 수 있습니까? – dun

0

당신은 또한 for 루프 내에서 직접 파일에 쓸 수 for 루프

all_divs = soup.select("div.large-image") 

    for item in all_divs: 
     div += str(item) 
     time += 1 

또는 join()

time = len(all_divs) 

    div = ''.join(str(item) for item in all_divs) 

를 사용하여 내부의 모든 항목을 연결할 수 있으며

for item in all_divs: 
     csv_writer.writerow([str(item).strip()]) 
     time += 1 
을 행에 도착

작업 예제

import urllib.request 
from bs4 import BeautifulSoup 
import csv 

div = "" 
time = 0 

f = open('output.csv', 'w') 
csv_writer = csv.writer(f) 

all_urls = [ 
    "https://www.kramerav.com/de/Product/VM-2N", 
    "https://www.kramerav.com/de/Product/SDIA-IN2-F16", 
] 

for url in all_urls: 
    print('url:', url) 

    html = urllib.request.urlopen(url).read() 

    try: 
     soup = BeautifulSoup(html) 
     all_divs = soup.select("div.large-image") 

     for item in all_divs: 
      div += str(item) 
      time += 1 

     # or  
     time = len(all_divs) 
     div = ''.join(str(item) for item in all_divs) 

     # or 

     for item in all_divs: 
      #div += str(item) 
      #time += 1 
      csv_writer.writerow([time, str(item).strip()]) 

    except IndexError as ex: 
     print('Error:', ex) 
     time += 1 
    finally: 
     print(time, div) 

f.close()