tôi sử dụng cách tiếp cận Scrapy Extensions để mở rộng các lớp Spider để một lớp có tên Masterspider bao gồm một phân tích cú pháp chung chung.
Dưới đây là phiên bản "ngắn" rất ngắn của trình phân tích cú pháp mở rộng chung của tôi. Lưu ý rằng bạn cần triển khai trình kết xuất với công cụ Javascript (chẳng hạn như Selenium hoặc BeautifulSoup) ngay sau khi bạn bắt đầu làm việc trên các trang bằng AJAX. Và rất nhiều mã bổ sung để quản lý sự khác biệt giữa các trang web (phế liệu dựa trên tiêu đề cột, xử lý tương đối so với URL dài, quản lý các loại vùng chứa dữ liệu khác nhau, v.v ...).
Điều gì đang gây nhiễu với phương pháp Tiếp cận tiện ích mở rộng là bạn vẫn có thể ghi đè phương pháp phân tích cú pháp chung nếu có điều gì đó không phù hợp nhưng tôi chưa bao giờ phải làm như vậy. Lớp Masterspider kiểm tra xem một số phương thức đã được tạo ra chưa (ví dụ: parser_start, next_url_parser ...) trong lớp spider cụ thể của trang web để cho phép quản lý các đặc trưng: gửi biểu mẫu, xây dựng yêu cầu next_url từ các phần tử trong trang, v.v.
Khi tôi đang cạo các trang web khác nhau, luôn có các tính năng cụ thể để quản lý. Đó là lý do tại sao tôi muốn giữ một lớp cho mỗi trang web được cạo để tôi có thể viết một số phương pháp cụ thể để xử lý nó (trước/sau xử lý ngoại trừ PipeLines, Request generator ...).
masterspider/sitespider/settings.py
EXTENSIONS = {
'masterspider.masterspider.MasterSpider': 500
}
masterspider/masterspdier/masterspider.py
# -*- coding: utf8 -*-
from scrapy.spider import Spider
from scrapy.selector import Selector
from scrapy.http import Request
from sitespider.items import genspiderItem
class MasterSpider(Spider):
def start_requests(self):
if hasattr(self,'parse_start'): # First page requiring a specific parser
fcallback = self.parse_start
else:
fcallback = self.parse
return [ Request(self.spd['start_url'],
callback=fcallback,
meta={'itemfields': {}}) ]
def parse(self, response):
sel = Selector(response)
lines = sel.xpath(self.spd['xlines'])
# ...
for line in lines:
item = genspiderItem(response.meta['itemfields'])
# ...
# Get request_url of detailed page and scrap basic item info
# ...
yield Request(request_url,
callback=self.parse_item,
meta={'item':item, 'itemfields':response.meta['itemfields']})
for next_url in sel.xpath(self.spd['xnext_url']).extract():
if hasattr(self,'next_url_parser'): # Need to process the next page URL before?
yield self.next_url_parser(next_url, response)
else:
yield Request(
request_url,
callback=self.parse,
meta=response.meta)
def parse_item(self, response):
sel = Selector(response)
item = response.meta['item']
for itemname, xitemname in self.spd['x_ondetailpage'].iteritems():
item[itemname] = "\n".join(sel.xpath(xitemname).extract())
return item
masterspider/sitespider/nhện/somesite_spider.py
# -*- coding: utf8 -*-
from scrapy.spider import Spider
from scrapy.selector import Selector
from scrapy.http import Request
from sitespider.items import genspiderItem
from masterspider.masterspider import MasterSpider
class targetsiteSpider(MasterSpider):
name = "targetsite"
allowed_domains = ["www.targetsite.com"]
spd = {
'start_url' : "http://www.targetsite.com/startpage", # Start page
'xlines' : "//td[something...]",
'xnext_url' : "//a[contains(@href,'something?page=')]/@href", # Next pages
'x_ondetailpage' : {
"itemprop123" : u"id('someid')//text()"
}
}
# def next_url_parser(self, next_url, response): # OPTIONAL next_url regexp pre-processor
# ...
Bạn có thể hiển thị mã mà bạn sử dụng cho các giá trị cố định của tên miền, từ khóa, thẻ không? – jfs
Đã thêm mã. Nó sử dụng BeautifulSoup để phân tích cú pháp html. – user1284717
này, đừng quá lười biếng bạn tôi. –