Python2.7에서 효과적인 크롤러를 만드는 방법 (How to make an effective crawler in Python2.7)


문제 설명

Python2.7에서 효과적인 크롤러를 만드는 방법 (How to make an effective crawler in Python2.7)

사용 가능한 각 제품의 가격과 정보를 얻기 위해 몇 겹의 옷을 크롤링하고 있지만 실제 알고리즘을 사용하면 완료하는 데 며칠이 걸리고 각 제품의 서로 다른 링크를 가져옵니다. 예를 들어 제품에 5가지 색상에 대한 5개의 링크가 있는 경우 5개의 링크가 있으며, 예를 들어 다음과 같이 92k 항목의 데이터베이스와 5k 제품만 있습니다.

https://i.gyazo.com/410d4faa33e2fbccf8979c5399856dd3.png

i.gyazo.com/b6118e67205d153272df001fb5efcfc8.png" rel="nofollow">https://i.gyazo.com/b6118e67205d153272df001fb5efcfc8.png 제품 ID

다른 링크입니다.

그래서 저는 아이디어와 이를 개선하기 위해 구현하는 방법을 원합니다. 예를 들어 제품 ID가 있으므로 해당 ID가 포함된 링크 하나를 이미 방문한 경우 다시는 거기에 들어가고 싶지 않습니다. 그리고 모든 웹을 크롤링하고 싶지만 제품이 포함된 웹사이트만 방문하고 싶습니다... 하지만 그 두 가지 아이디어를 구현하는 방법을 모르겠습니다./

현재 내 코드는 다음과 같습니다(너무 느림 그리고 너무 많이 반복됨):

import urllib
import urlparse
from itertools import ifilterfalse
from urllib2 import URLError, HTTPError

from bs4 import BeautifulSoup

urls = {"http://www.kiabi.es/"}
visited = set()


def get_html_text(url):
    try:
        return urllib.urlopen(current_url.encode('ascii','ignore')).read()
    except (IOError,URLError, HTTPError, urllib.ContentTooShortError):
        print "Error getting " + current_url
        urls.add(current_url)


def find_internal_links_in_html_text(html_text, base_url):
    soup = BeautifulSoup(html_text, "html.parser")
    links = set()
    for tag in soup.findAll('a', href=True):
        url = urlparse.urljoin(base_url, tag['href'])
        domain = urlparse.urlparse(base_url).hostname
        if domain in url:
            links.add(url)
    return links


def is_url_already_visited(url):
    return url in visited


while urls:
  try:
    word = '#C'
    current_url = urls.pop()
    print "Parsing", current_url
    if word in current_url:


        print "Parsing", current_url
        htmltext= urllib.urlopen(current_url).read()
        soup= BeautifulSoup(htmltext)

        [get the product info and save it into a sql database]

    html_text = get_html_text(current_url)
    visited.add(current_url)
    found_urls = find_internal_links_in_html_text(html_text, current_url)
    new_urls = ifilterfalse(is_url_already_visited, found_urls)
    urls.update(new_urls)

except Exception:
    pass  

예를 들어, 해당 크롤러에서 "#C"라는 단어를 사용하여 제품 페이지라는 것을 알고 정보를 얻을 수 있지만 어떻게 해당 URL에 내가 이미 방문한 제품 ID가 있는지 구별하기 위해 관련 없는 URL을 피하는 방법을 모릅니다. 그렇기 때문에 프로그램이 너무 느리고 동일한 링크를 많이 가져옵니다.

감사합니다. 돕다,


참조 솔루션

방법 1:

I would recommend using Scrapy. My answer is based on its great features.

Quoting your doubts:


I don't know how to avoid irrelevant urls

Answer: To avoid visiting irrelevant URLs you should use a Crawler with certain logic based on your use case. That said, you could use CrawlSpider and define your own Crawling rules where each Rule defines a certain behaviour for crawling the site so you won't visit irrelevant URLs.

Here is an example: http://doc.scrapy.org/en/latest/topics/spiders.html#crawlspider‑example


...but I don't know how to distinguish if that url has a product ID that I already visited...

Answer: By default, Scrapy uses RFPDupeFilter as its DUPEFILTER_CLASS which is used to detect and filter duplicate requests. RFPDupeFilter filters based on request fingerprint using the scrapy.utils.request.request_fingerprint function.

This is a Scrapy log output sample for duplicated requests:

2015‑11‑23 14:26:48 [scrapy] DEBUG: Filtered duplicate request: <GET http://doc.scrapy.org/en/latest/topics/request‑response.html> ‑ no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates)

Here is a Scrapy tutorial if you haven't worked with it yet: http://doc.scrapy.org/en/latest/intro/tutorial.html

(by Joel Sánchez LópezAndrés Pérez‑Albela H.)

참조 문서

  1. How to make an effective crawler in Python2.7 (CC BY‑SA 2.5/3.0/4.0)

#web-crawler #Python #beautifulsoup #web-scraping






관련 질문

UnicodeError: URL에 ASCII가 아닌 문자가 포함되어 있습니다(Python 2.7). (UnicodeError: URL contains non-ASCII characters (Python 2.7))

크롤링 출력 - 두 변수 연결 (Crawling output - connecting two variables)

Python2.7에서 효과적인 크롤러를 만드는 방법 (How to make an effective crawler in Python2.7)

이 텍스트가 다른 기사의 일부임을 Google에 알리는 방법 (How to tell google this text is part of another article)

크롤링하는 HTML 페이지에서 JavaScript 개체를 구문 분석하는 방법은 무엇입니까? (How to parse a JavaScript object from a HTML page I crawl?)

데이터 크롤링 또는 API 사용 (Crawling data or using API)

파이썬을 사용하여 웹사이트에서 내부 링크만 크롤링 (Crawl only internal links from a website using python)

받은 응답에서 HTML 코드를 긁는 방법은 무엇입니까? (How to scrape the html code from the response received?)

PHP를 사용하여 웹 사이트에서 클래스 이름 스크래핑 (Scraping class name on a website using php)

Scrapy Spider를 사용하는 Craigslist Scraper가 기능을 수행하지 않음 (Craigslist Scraper using Scrapy Spider not performing functions)

BeautifulSoup: 이 링크에서 모든 기사 링크를 가져오는 방법은 무엇입니까? (BeautifulSoup: how to get all article links from this link?)

나는 클라이언트입니다. 선택적으로 http 응답에서 헤더를 제거할 수 있습니까? (I'm client. Can I remove header from http response optionally?)







코멘트