2015-10-03 18 views
5

Tôi đã làm việc trên một trình thu thập dữ liệu web thu thập thông tin qua tất cả các liên kết nội bộ từ url bắt đầu và chỉ thu thập các liên kết bên ngoài với scrapy. Tuy nhiên, vấn đề chính của tôi là phân loại các liên kết bên ngoài và các liên kết nội bộ. Ví dụ: khi tôi cố gắng lọc ra các liên kết bên ngoài với link.startswith("http") or link.startswith("ftp") or link.startswith("www"), nếu trang web liên kết trang web của riêng nó với đường dẫn tuyệt đối (www.my-domain.com/about thay vì /about) thì nó sẽ phân loại nó thành liên kết bên ngoài ngay cả khi không. Sau đây là mã của tôi:Phế liệu: lưu trữ tất cả các liên kết bên ngoài và thu thập thông tin tất cả các liên kết nội bộ

import scrapy 
from lab_relationship.items import Links 

class WebSpider(scrapy.Spider): 
    name = "web" 
    allowed_domains = ["my-domain.com"] 
    start_urls = (
     'www.my-domain.com', 
    ) 

    def parse(self, response): 
     """ finds all external links""" 
     items = [] 
     for link in set(response.xpath('//a/@href').extract()): 
      item = Links() 
      if len(link) > 1: 
       if link.startswith("/") or link.startswith("."): 
        # internal link 
        url = response.urljoin(link) 
        item['internal'] = url 
        #yield scrapy.Request(url, self.parse) 
       elif link.startswith("http") or link.startswith("ftp") or link.startswith("www"): 
        # external link 
        item['external'] = link 
       else: 
        # misc. links: mailto, id (#) 
        item['misc'] = link 
       items.append(item) 
     return items 

Mọi đề xuất?

Trả lời

7

Sử dụng link extractor.

Khi khởi tạo, bạn phải chuyển miền được phép. Bạn không phải lo lắng về việc chỉ định các thẻ bắt buộc, vì (theo tài liệu) tham số tags mất ('a', 'area') theo mặc định.

Trên ví dụ về trang web Rust lang, mã để in tất cả các liên kết nội bộ từ miền của họ sẽ như thế nào:

import scrapy 
from scrapy.linkextractors import LinkExtractor 


class RustSpider(scrapy.Spider): 
    name = "rust" 
    allowed_domains = ["www.rust-lang.org"] 
    start_urls = (
     'http://www.rust-lang.org/', 
    ) 

    def parse(self, response): 
     extractor = LinkExtractor(allow_domains='rust-lang.org') 
     links = extractor.extract_links(response) 
     for link in links: 
      print link.url 

và đầu ra sẽ là một danh sách các liên kết như vậy: https://doc.rust-lang.org/nightly/reference.html (Tôi có thể' t đăng bài nhiều hơn), trong khi loại trừ tất cả các liên kết như các liên kết đến StackOverflow.

Hãy chắc chắn kiểm tra trang tài liệu, vì trình trích xuất liên kết có nhiều thông số bạn có thể cần.

+0

Hm .. bạn đang gợi ý tạo một tập hợp các liên kết nội bộ với LinkExtractor và cho tất cả các liên kết, hãy kiểm tra xem chúng có khớp với các liên kết nội bộ hay không và nếu không, chúng là các liên kết bên ngoài? –

+0

Không chính xác, bằng cách đặt 'deny_domains = 'domain'' bạn có thể trích xuất các liên kết không nằm trong một miền cụ thể (bên ngoài). –

+0

Oh man. Đó là hoàn hảo. Cảm ơn bạn rất nhiều. –

-2

Nếu có thể nhận nhiều hoặc câu, không chỉ hai.

+0

Nhưng mảng của tôi cũng sẽ bao gồm các liên kết nội bộ. Tôi chỉ muốn các liên kết bên ngoài –

+0

Có, chỉ cần lưu ý rằng. Nhìn vào mã của bạn, "if link.startswith ("/") hoặc link.startswith (". "):" Dòng có thể có nhiều "hoặc" câu lệnh, nếu không có thể sử dụng [switch] (https: // pypi. python.org/pypi/switch) statement – kcrk

+0

Tôi đã sử dụng nhiều 'hoặc' trong mã của mình, và tôi không thấy làm thế nào mà sẽ lọc ra các liên kết tuyệt đối từ liên kết tương đối –

Các vấn đề liên quan