Về cơ bản, bạn có rất nhiều công cụ để lựa chọn:
Những công cụ này có mục đích khác nhau nhưng chúng có thể được pha trộn với nhau tùy thuộc vào nhiệm vụ.
Phế liệu là một công cụ mạnh mẽ và rất thông minh để thu thập dữ liệu trang web, trích xuất dữ liệu. Tuy nhiên, khi nói đến việc thao tác trang: nhấn nút, điền hình thức - nó trở nên phức tạp hơn:
- đôi khi, thật dễ dàng để mô phỏng điền/nộp tờ bằng cách làm cho hình thức hành động cơ bản trực tiếp trong scrapy
- đôi khi, bạn phải sử dụng các công cụ khác để trợ giúp - giống như cơ giới hóa hoặc selenium
Nếu bạn đặt câu hỏi cụ thể hơn, nó sẽ giúp bạn hiểu loại công cụ bạn nên sử dụng hoặc lựa chọn.
Hãy xem ví dụ về sự kết hợp selenium đầy bụi bẩn thú vị &. Ở đây, nhiệm vụ selen là nhấp vào nút và cung cấp dữ liệu cho các hạng mục scrapy:
import time
from scrapy.item import Item, Field
from selenium import webdriver
from scrapy.spider import BaseSpider
class ElyseAvenueItem(Item):
name = Field()
class ElyseAvenueSpider(BaseSpider):
name = "elyse"
allowed_domains = ["ehealthinsurance.com"]
start_urls = [
'http://www.ehealthinsurance.com/individual-family-health-insurance?action=changeCensus&census.zipCode=48341&census.primary.gender=MALE&census.requestEffectiveDate=06/01/2013&census.primary.month=12&census.primary.day=01&census.primary.year=1971']
def __init__(self):
self.driver = webdriver.Firefox()
def parse(self, response):
self.driver.get(response.url)
el = self.driver.find_element_by_xpath("//input[contains(@class,'btn go-btn')]")
if el:
el.click()
time.sleep(10)
plans = self.driver.find_elements_by_class_name("plan-info")
for plan in plans:
item = ElyseAvenueItem()
item['name'] = plan.find_element_by_class_name('primary').text
yield item
self.driver.close()
UPDATE:
Dưới đây là một ví dụ về cách sử dụng scrapy trong trường hợp của bạn:
from scrapy.http import FormRequest
from scrapy.item import Item, Field
from scrapy.selector import HtmlXPathSelector
from scrapy.spider import BaseSpider
class AcrisItem(Item):
borough = Field()
block = Field()
doc_type_name = Field()
class AcrisSpider(BaseSpider):
name = "acris"
allowed_domains = ["a836-acris.nyc.gov"]
start_urls = ['http://a836-acris.nyc.gov/DS/DocumentSearch/DocumentType']
def parse(self, response):
hxs = HtmlXPathSelector(response)
document_classes = hxs.select('//select[@name="combox_doc_doctype"]/option')
form_token = hxs.select('//input[@name="__RequestVerificationToken"]/@value').extract()[0]
for document_class in document_classes:
if document_class:
doc_type = document_class.select('.//@value').extract()[0]
doc_type_name = document_class.select('.//text()').extract()[0]
formdata = {'__RequestVerificationToken': form_token,
'hid_selectdate': '7',
'hid_doctype': doc_type,
'hid_doctype_name': doc_type_name,
'hid_max_rows': '10',
'hid_ISIntranet': 'N',
'hid_SearchType': 'DOCTYPE',
'hid_page': '1',
'hid_borough': '0',
'hid_borough_name': 'ALL BOROUGHS',
'hid_ReqID': '',
'hid_sort': '',
'hid_datefromm': '',
'hid_datefromd': '',
'hid_datefromy': '',
'hid_datetom': '',
'hid_datetod': '',
'hid_datetoy': '', }
yield FormRequest(url="http://a836-acris.nyc.gov/DS/DocumentSearch/DocumentTypeResult",
method="POST",
formdata=formdata,
callback=self.parse_page,
meta={'doc_type_name': doc_type_name})
def parse_page(self, response):
hxs = HtmlXPathSelector(response)
rows = hxs.select('//form[@name="DATA"]/table/tbody/tr[2]/td/table/tr')
for row in rows:
item = AcrisItem()
borough = row.select('.//td[2]/div/font/text()').extract()
block = row.select('.//td[3]/div/font/text()').extract()
if borough and block:
item['borough'] = borough[0]
item['block'] = block[0]
item['doc_type_name'] = response.meta['doc_type_name']
yield item
Lưu nó trong spider.py
và chạy qua scrapy runspider spider.py -o output.json
và trong output.json
bạn sẽ thấy:
{"doc_type_name": "CONDEMNATION PROCEEDINGS ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "CERTIFICATE OF REDUCTION ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "COLLATERAL MORTGAGE ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "CERTIFIED COPY OF WILL ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "CONFIRMATORY DEED ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "CERT NONATTCHMENT FED TAX LIEN ", "borough": "Borough", "block": "Block"}
...
Hy vọng rằng sẽ giúp.
Trình điều khiển Selenium Firefox tiêu thụ khoảng 100MB bộ nhớ cho một trường hợp và yêu cầu của tôi là chạy nhiều lần cùng một lúc để làm cho quá trình cạo nhanh chóng để có giới hạn bộ nhớ. Đôi khi Firefox gặp sự cố trong khi thực hiện scraper, không biết tại sao. Ngoài ra tôi cần cửa sổ ít cạo mà không phải là có thể trong trường hợp của trình điều khiển Selenium Firefox. Mục tiêu cuối cùng của tôi là chạy các mẩu tin lưu niệm trên Heroku và tôi có môi trường Linux ở đó vì vậy trình điều khiển Firefox selenium sẽ không hoạt động trên Heroku. –
Ok, trông giống như một biểu mẫu html đơn giản gửi yêu cầu đăng bài. Chỉ cần sử dụng phế liệu là đủ. Về lý thuyết, nó phải như thế này: cạo trang chính, nhận các lựa chọn từ các trường chọn, bắt đầu [Yêu cầu] (http://doc.scrapy.org/en/latest/topics/request-response.html # scrapy.http.Request) với một cuộc gọi lại - thu thập thông tin dữ liệu vào các mục cào trong cuộc gọi lại. Nếu bạn muốn, tôi có thể cung cấp một ví dụ. – alecxe
Xin vui lòng, nó sẽ thực sự hữu ích cho tôi nếu bạn có thể đưa ra một ví dụ nhỏ về việc thực hiện. –