Python버전 관리: pyenv 및 pyenv-virtualenv
Scrapy 크롤러 입문 튜토리얼 1설치 및 기본 사용
Scrapy 크롤러 입문 튜토리얼 2 공식적으로 제공되는 데모
Scrapy 크롤러 입문 튜토리얼 3 명령줄 도구 소개 및 예시
Scrapy 크롤러 입문 튜토리얼 4 Spider(크롤러)
Scrapy 크롤러 입문 튜토리얼 5 선택기(선택기)
Scrapy 크롤러 입문 튜토리얼 6 항목(프로젝트)
Scrapy 크롤러 입문 튜토리얼 7 아이템 로더(프로젝트 로더)
Scrapy 크롤러 입문 튜토리얼 8 편리한 디버깅
을 위한 대화형 셸 Scrapy 크롤러 입문 튜토리얼 9 항목 파이프라인(프로젝트 파이프라인)
Scrapy 크롤러 입문 튜토리얼 10 피드 내보내기(파일 내보내기)
Scrapy 크롤러 입문 튜토리얼 11 요청 및 응답(요청 및 응답)
Scrapy 크롤러 입문 튜토리얼 12개 링크 추출or(링크 추출기)
[toc]
개발 환경: Python 3.6.0 版本
(현재 최신) Scrapy 1.3.2 版本
(현재 최신)
크롤러는 웹 사이트(또는 웹 사이트의 A 클래스)를 크롤링하는 방법을 정의합니다. 크롤링을 수행하는 방법(예: 링크 따라가기) 및 웹 페이지에서 구조화된 데이터를 추출하는 방법(예: 크롤링 항목)을 포함합니다. 즉, 스파이더는 특정 항목에 사용되도록 정의하는 클래스입니다. 웹사이트(또는 특정 웹사이트)에서는 사용자 정의 동작 으로 웹페이지를 크롤링하고 구문 분석합니다. 여기서
크롤러의 경우 루프 은 다음과 같은 과정을 거칩니다.
첫 번째 URL을 스크랩하기 위한 초기 요청을 생성한 후 응답과 함께 호출할 콜백 함수를 지정합니다. > 첫 번째로 실행된 요청은 start_requests()를 호출하여 얻습니다(기본값). 요청은 start_urls에 지정된
URL에 대한 콜백 함수에서 응답(웹페이지)을 구문 분석하고 추출된 데이터가 포함된 객체, Item<a href="http://www.php.cn/wiki/164.html" target="_blank">클래스<p> scrapy.spiders.Spider</p></a>
<a href="http://www.php.cn/wiki/164.html" target="_blank">class</a> scrapy.spiders.Spider
속성 에서 요청을 보내는 기본 start_requests()
구현을 제공하고 start_urlsspider
는 각 결과 응답에 대해 메서드를 호출합니다. parse
spider
문자열name
입니다. 크롤러 이름은 Scrapy가 크롤러를 찾고 인스턴스화하는 방법이므로
고유해야 합니다. 그러나 동일한 크롤러의 여러 인스턴스를 인스턴스화하는 데 방해가 되는 것은 없습니다. 이는 가장 중요한 크롤러 속성이며 필수입니다. 크롤러가 단일 도메인 이름을 크롤링하는 경우 일반적으로 도메인 이름을 따서 크롤러 이름을 지정합니다. 예를 들어 mywebsite.com을 크롤링하는 크롤러는 일반적으로 mywebsite라고 합니다.
참고
Python 2에서는 ASCII여야 합니다. allowed_do<a href="http://www.php.cn/wiki/646.html" target="_blank">기본<br></a>
다른 목록allowed_do<a href="http://www.php.cn/wiki/646.html" target="_blank">main</a>s
은 크롤링되지 않습니다.
custom_<a href="http://www.php.cn/code/8209.html" target="_blank">set</a>tings
이 크롤러를 실행할 때 프로젝트 전체 구성에서 재정의될 설정 사전입니다. 인스턴스화 전에 설정이 업데이트되므로 클래스 속성으로 정의해야 합니다.
crawler
이 속성은 클래스를 초기화한 후 클래스 메소드 from_crawler()에 의해 설정되며 크롤러 인스턴스가 바인딩된 개체에 크롤러를 연결합니다.
미들웨어, 신호 관리자 등)를 캡슐화합니다. 자세한 내용은 크롤러API를 참조하세요.
settings
이 크롤러를 실행하기 위한 구성입니다. 이는 설정 인스턴스입니다. 이 주제에 대한 자세한 소개는 설정 테마를 참조하세요.
logger
Spider로 만든 Python 로거
. 크롤러 로깅에 설명된 대로 이를 사용하여 로그 메시지를 보낼 수 있습니다. name
(crawler, from_crawler
args, * kwargs) 는 Scrapy가 크롤러를 생성하는 데 사용하는 클래스 메서드입니다.
주어진 인수 args 및 명명된 인수 kwargs를 사용하여 메서드를 호출합니다. init()
init() 메서드에 전달된 인수
init() 메소드에 대한 키워드 인수
이 메소드는 이 크롤러를 크롤링하기 위한 첫 번째 요청의 반복 가능 항목을 반환해야 합니다. start_requests()
start_requests()로는 start_urls를 쓰지 않고, 써도 소용이 없습니다.
기본 구현은 start_urls이지만 start_requests 메소드를 재정의할 수 있습니다.
예를 들어POST 요청
을 사용하여 로그인하여 시작해야 하는 경우 다음을 수행할 수 있습니다. class MySpider(scrapy.Spider):
name = 'myspider'
def start_requests(self):
return [scrapy.FormRequest("http://www.example.com/login",
formdata={'user': 'john', 'pass': 'secret'},
callback=self.logged_in)]
def logged_in(self, response):
# here you would extract links to follow and return Requests for
# each of them, with another callback
pass
URL을 수신하고 크롤링을 위한 요청 개체(또는 요청 개체 목록) 방법입니다. 이 메소드는 start_requests() 메소드 내에서 초기 요청을 구성하는 데 사용되며 일반적으로 URL을 요청으로 변환하는 데 사용됩니다. make_requests_from_url(url)
재정의되지 않는 한, 이 메소드는 콜백 함수로 구문 분석() 메소드를 사용하고 dont_filter 매개변수가 활성화된 요청을 반환합니다(자세한 내용은 요청 클래스 참조).
이것은 요청에 콜백이 지정되지 않은 경우 다운로드된 응답을 처리하기 위한 Scrapy의 기본 콜백입니다. parse(response)
파싱 메소드는 응답을 처리하고 크롤링된 데이터 또는 추가 URL을 반환하는 역할을 합니다. 다른 요청 콜백에는 Spider 클래스와 동일한 요구 사항이 있습니다.
이 메소드와 기타 요청 콜백은 요청 및 사전 또는 항목 객체의 반복 가능 항목을 반환해야 합니다.
크롤러를 통해 로거에 로그 메시지를 전송하고 이전 버전과의 호환성을 유지하는 래퍼입니다. 자세한 내용은 Spider에서 로깅을 참조하세요. log(message[, level, component])
크롤러가 닫힐 때 소환됩니다. 이 메소드는 spider_closed 신호에 대한 signal.connect()에 대한 지름길을 제공합니다. closed(reason)
예를 살펴보겠습니다.
import scrapy class MySpider(scrapy.Spider): name = 'example.com' allowed_domains = ['example.com'] start_urls = [ 'http://www.example.com/1.html', 'http://www.example.com/2.html', 'http://www.example.com/3.html', ] def parse(self, response): self.logger.info('A response from %s just arrived!', response.url)
단일 콜백에서 여러 요청 및 항목 반환:
import scrapy class MySpider(scrapy.Spider): name = 'example.com' allowed_domains = ['example.com'] start_urls = [ 'http://www.example.com/1.html', 'http://www.example.com/2.html', 'http://www.example.com/3.html', ] def parse(self, response): for h3 in response.xpath('//h3').extract(): yield {"title": h3} for url in response.xpath('//a/@href').extract(): yield scrapy.Request(url, callback=self.parse)
start_urls 대신 start_requests()를 직접 사용할 수 있습니다. 더 편리하게 얻을 수 있습니다:
import scrapy from myproject.items import MyItem class MySpider(scrapy.Spider): name = 'example.com' allowed_domains = ['example.com'] def start_requests(self): yield scrapy.Request('http://www.example.com/1.html', self.parse) yield scrapy.Request('http://www.example.com/2.html', self.parse) yield scrapy.Request('http://www.example.com/3.html', self.parse) def parse(self, response): for h3 in response.xpath('//h3').extract(): yield MyItem(title=h3) for url in response.xpath('//a/@href').extract(): yield scrapy.Request(url, callback=self.parse)
스파이더 인수
Spider 크롤링 매개변수는 -a 옵션을 사용하여 명령을 통해 전달됩니다. 예:
scrapy crawl myspider -a category=electronics
크롤러는
메소드의 매개변수에 액세스할 수 있습니다. import scrapy
class MySpider(scrapy.Spider):
name = 'myspider'
def init(self, category=None, *args, **kwargs):
super(MySpider, self).init(*args, **kwargs)
self.start_urls = ['http://www.example.com/categories/%s' % category]
# ...
메소드는 다음과 같습니다. 크롤러 매개변수를 가져와 속성으로 크롤러에 복사합니다. 위의 예는 다음과 같이 작성할 수도 있습니다. import scrapy
class MySpider(scrapy.Spider):
name = 'myspider'
def start_requests(self):
yield scrapy.Request('http://www.example.com/categories/%s' % self.category)
.loads 등을 사용하여 직접 목록으로 구문 분석한 다음 속성으로 설정해야 합니다. 그렇지 않으면 start_urls 문자열(매우 일반적인 Python 트랩)을 반복하게 되어 각 문자가 별도의 URL로 처리됩니다. 有效的用例是设置使用的http验证凭据HttpAuthMiddleware 或用户代理使用的用户代理UserAgentMiddleware: Spider参数也可以通过Scrapyd schedule.jsonAPI 传递。请参阅Scrapyd文档。 Scrapy附带一些有用的通用爬虫,你可以使用它来子类化你的爬虫。他们的目的是为一些常见的抓取案例提供方便的功能,例如根据某些规则查看网站上的所有链接,从站点地图抓取或解析XML / CSV Feed。 对于在以下爬虫中使用的示例,我们假设您有一个 除了从Spider继承的属性(你必须指定),这个类支持一个新的属性: 这个爬虫还暴露了可覆盖的方法: 警告 现在让我们来看一个CrawlSpider的例子: 这个爬虫会开始抓取example.com的主页,收集类别链接和项链接,用parse_item方法解析后者。对于每个项目响应,将使用XPath从HTML中提取一些数据,并将Item使用它填充。 要设置迭代器和标记名称,必须定义以下类属性: 然后,您可以在属性中指定具有命名空间的itertag 节点。 例: 除了这些新的属性,这个爬虫也有以下可重写的方法: 这些爬虫很容易使用,让我们看一个例子: 基本上我们做的是创建一个爬虫,从给定的下载一个start_urls,然后遍历每个item标签,打印出来,并存储一些随机数据Item。 让我们看一个类似于前一个例子,但使用 CSVFeedSpider: 它支持嵌套Sitemap和从robots.txt发现Sitemap网址 。 您还可以指向robots.txt,它会解析为从中提取Sitemap网址。 regex是与从Sitemap中提取的网址相匹配的正则表达式。 regex可以是一个str或一个编译的正则表达式对象。 callback是用于处理与正则表达式匹配的url的回调。callback可以是字符串(指示蜘蛛方法的名称)或可调用的。 例如: 规则按顺序应用,只有匹配的第一个将被使用。 默认情况下,将跟踪所有网站地图。 例如: 使用 默认为 最简单的示例:使用parse回调处理通过站点地图发现的所有网址 : 使用某个回调处理一些网址,并使用不同的回调处理其他网址: 关注robots.txt文件中定义的sitemaps,并且只跟踪其网址包含 将SitemapSpider与其他来源网址结合使用: scrapy crawl myspider -a http_user=myuser -a http_pass=mypassw<a href="http://www.php.cn/wiki/1360.html" target="_blank">ord</a> -a user_agent=mybot
通用爬虫
TestItem
在myproject.items
模块中声明的项目:import scrapy
class TestItem(scrapy.Item):
id = scrapy.Field()
name = scrapy.Field()
description = scrapy.Field()
抓取爬虫
类 scrapy.spiders.CrawlSpider
这是最常用的爬行常规网站的爬虫,因为它通过定义一组规则为下列链接提供了一种方便的机制。它可能不是最适合您的特定网站或项目,但它是足够通用的几种情况,所以你可以从它开始,根据需要覆盖更多的自定义功能,或只是实现自己的爬虫。rules
它是一个(或多个)Rule
对象的列表。每个都Rule
定义了抓取网站的某种行为。规则对象如下所述。如果多个规则匹配相同的链接,则将根据它们在此属性中定义的顺序使用第一个。parse_start_url(response)
对于start_urls响应调用此方法。它允许解析初始响应,并且必须返回Item
对象,Request
对象或包含任何对象的迭代器。抓取规则
class scrapy.spiders.Rule(link_extractor,callback = None,cb_kwargs = None,follow = None,process_links = None,process_request = None )
link_extractor
是一个链接提取程序对象,它定义如何从每个爬网页面提取链接。callback
是一个可调用的或字符串(在这种情况下,将使用具有该名称的爬虫对象的方法),以便为使用指定的link_extractor提取的每个链接调用。这个回调接收一个响应作为其第一个参数,并且必须返回一个包含Item和 Request对象(或它们的任何子类)的列表。
当编写爬网爬虫规则时,避免使用parse
作为回调,因为CrawlSpider
使用parse
方法本身来实现其逻辑。所以如果你重写的parse
方法,爬行爬虫将不再工作。cb_kwargs
是包含要传递给回调函数的关键字参数的dict。follow
是一个布尔值,它指定是否应该从使用此规则提取的每个响应中跟踪链接。如果callback
是None follow
默认为True
,否则默认为False
。process_links
是一个可调用的或一个字符串(在这种情况下,将使用具有该名称的爬虫对象的方法),将使用指定从每个响应提取的每个链接列表调用该方法link_extractor
。这主要用于过滤目的。process_request
是一个可调用的或一个字符串(在这种情况下,将使用具有该名称的爬虫对象的方法),它将被此规则提取的每个请求调用,并且必须返回一个请求或无(过滤出请求) 。抓取爬虫示例
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class MySpider(CrawlSpider):
name = 'example.com'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com']
rules = (
# Extract links matching 'category.php' (but not matching 'subsection.php')
# and follow links from them (since no callback means follow=True by default).
Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),
# Extract links matching 'item.php' and parse them with the spider's method parse_item
Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),
)
def parse_item(self, response):
self.logger.info('Hi, this is an item page! %s', response.url)
item = scrapy.Item()
item['id'] = response.xpath('//td[@id="item_id"]/text()').re(r'ID: (\d+)')
item['name'] = response.xpath('//td[@id="item_name"]/text()').extract()
item['description'] = response.xpath('//td[@id="item_description"]/text()').extract()
return item
XMLFeedSpider
class scrapy.spiders.XMLFeedSpider
XMLFeedSpider设计用于通过以特定节点名称迭代XML订阅源来解析XML订阅源。迭代器可以选自:iternodes,xml和html。iternodes为了性能原因,建议使用迭代器,因为xml和迭代器html一次生成整个DOM为了解析它。但是,html当使用坏标记解析XML时,使用作为迭代器可能很有用。
iterator
定义要使用的迭代器的字符串。它可以是:
'iternodes'
- 基于正则表达式的快速迭代器'html'
- 使用的迭代器Selector。请记住,这使用DOM解析,并且必须加载所有DOM在内存中,这可能是一个大饲料的问题'xml'
- 使用的迭代器Selector。请记住,这使用DOM解析,并且必须加载所有DOM在内存中,这可能是一个大饲料的问题
它默认为:'iternodes'
。itertag
一个具有要迭代的节点(或元素)的名称的字符串。示例:itertag = 'product'
namespaces
定义该文档中将使用此爬虫处理的命名空间的元组列表。在 与将用于自动注册使用的命名空间 的方法。(prefix, uri)prefixuriregister_namespace()class YourSpider(XMLFeedSpider):
namespaces = [('n', 'http://www.sitemaps.org/schemas/sitemap/0.9')]
itertag = 'n:url'
# ...
adapt_response(response)
一种在爬虫开始解析响应之前,在响应从爬虫中间件到达时立即接收的方法。它可以用于在解析之前修改响应主体。此方法接收响应并返回响应(它可以是相同的或另一个)。parse_node(response, selector)
对于与提供的标记名称(itertag)匹配的节点,将调用此方法。接收Selector每个节点的响应和 。覆盖此方法是必需的。否则,你的爬虫将不工作。此方法必须返回一个Item对象,一个 Request对象或包含任何对象的迭代器。process_results(response, results)
对于由爬虫返回的每个结果(Items or Requests),将调用此方法,并且它将在将结果返回到框架核心之前执行所需的任何最后处理,例如设置项目ID。它接收结果列表和产生那些结果的响应。它必须返回结果列表(Items or Requests)。XMLFeedSpider示例
from scrapy.spiders import XMLFeedSpider
from myproject.items import TestItem
class MySpider(XMLFeedSpider):
name = 'example.com'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com/feed.xml']
iterator = 'iternodes' # This is actually unnecessary, since it's the default value
itertag = 'item'
def parse_node(self, response, node):
self.logger.info('Hi, this is a <%s> node!: %s', self.itertag, ''.join(node.extract()))
item = TestItem()
item['id'] = node.xpath('@id').extract()
item['name'] = node.xpath('name').extract()
item['description'] = node.xpath('description').extract()
return item
CSVFeedSpider
class scrapy.spiders.CSVF
这个爬虫非常类似于XMLFeedSpider,除了它迭代行,而不是节点。在每次迭代中调用的方法是parse_row()。delimiter
CSV文件中每个字段的带分隔符的字符串默认为','(逗号)。quotechar
CSV文件中每个字段的包含字符的字符串默认为'"'(引号)。<a href="http://www.php.cn/html/html-HEAD-2.html" target="_blank">head</a>ers
文件CSV Feed中包含的行的列表,用于从中提取字段。parse_row(response, row)
使用CSV文件的每个提供(或检测到)标头的键接收响应和dict(表示每行)。这个爬虫还给予机会重写adapt_response和process_results方法的前和后处理的目的。CSVFeedSpider示例
from scrapy.spiders import CSVFeedSpider
from myproject.items import TestItem
class MySpider(CSVFeedSpider):
name = 'example.com'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com/feed.csv']
delimiter = ';'
quotechar = "'"
headers = ['id', 'name', 'description']
def parse_row(self, response, row):
self.logger.info('Hi, this is a row!: %r', row)
item = TestItem()
item['id'] = row['id']
item['name'] = row['name']
item['description'] = row['description']
return item
SitemapSpider
class scrapy.spiders.SitemapSpider
SitemapSpider允许您通过使用Sitemaps发现网址来抓取网站。sitemap_urls
指向您要抓取的网址的网站的网址列表。sitemap_rules
元组列表其中:(regex, callback)
sitemap_rules = [('/product/', 'parse_product')]
如果省略此属性,则会在parse回调中处理在站点地图中找到的所有网址。sitemap_follow
应遵循的网站地图的正则表达式列表。这只适用于使用指向其他Sitemap文件的Sitemap索引文件的网站。sitemap_alternate_links
指定是否url应遵循一个备用链接。这些是在同一个url块中传递的另一种语言的同一网站的链接。<url>
<loc>http://example.com/</loc>
<xhtml:link rel="alternate" hreflang="de" href="http://example.com/de"/>
</url>
sitemap_alternate_linksset
,这将检索两个URL。随着 sitemap_alternate_links
禁用,只有http://example.com/将进行检索。sitemap_alternate_links
禁用。SitemapSpider示例
from scrapy.spiders import SitemapSpider
class MySpider(SitemapSpider):
sitemap_urls = ['http://www.example.com/sitemap.xml']
def parse(self, response):
pass # ... scrape item here ...
from scrapy.spiders import SitemapSpider
class MySpider(SitemapSpider):
sitemap_urls = ['http://www.example.com/sitemap.xml']
sitemap_rules = [
('/product/', 'parse_product'),
('/category/', 'parse_category'),
]
def parse_product(self, response):
pass # ... scrape product ...
def parse_category(self, response):
pass # ... scrape category ...
/sitemap_shop
以下内容的Sitemap :from scrapy.spiders import SitemapSpider
class MySpider(SitemapSpider):
sitemap_urls = ['http://www.example.com/robots.txt']
sitemap_rules = [
('/shop/', 'parse_shop'),
]
sitemap_follow = ['/sitemap_shops']
def parse_shop(self, response):
pass # ... scrape shop here ...
from scrapy.spiders import SitemapSpider
class MySpider(SitemapSpider):
sitemap_urls = ['http://www.example.com/robots.txt']
sitemap_rules = [
('/shop/', 'parse_shop'),
]
other_urls = ['http://www.example.com/about']
def start_requests(self):
requests = list(super(MySpider, self).start_requests())
requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]
return requests
def parse_shop(self, response):
pass # ... scrape shop here ...
def parse_other(self, response):
pass # ... scrape other here ...
위 내용은 Scrapy 크롤러 입문 튜토리얼 4 Spider(크롤러)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!