在Python Scrapy中开发您的第一个Web爬虫

在这篇文章中,我将编写一个网络爬虫,它将从OLX的电子产品和设备项目中获取数据。在我进入代码之前,如何简要介绍Scrapy本身?

什么是Scrapy?

来自维基百科:

在Python Scrapy中开发您的第一个Web爬虫_第1张图片

Scrapy(/skre?pi/ skray-pee)[1]是一个免费的开源Web爬行框架,用Python编写。最初设计用于网页抓取,它也可以用于使用API??或作为通用网络爬虫提取数据。[2]它目前由网络抓取开发和服务公司Scrapinghub Ltd.维护。

一个Web爬行框架,它完成了编写爬虫所需的所有繁重工作。这些是什么,我将在下面进一步探讨。

继续阅读!

创建项目

Scrapy在单个项目中引入了具有多个爬虫或蜘蛛的项目的想法。如果您要编写站点的不同部分或站点的子域的多个爬虫,则此概念特别有用。所以,首先创建项目

在Python Scrapy中开发您的第一个Web爬虫_第2张图片

代码如下

Adnans-MBP:ScrapyCrawlers AdnanAhmad$ scrapy startproject olx

New Scrapy project 'olx', using template directory '//anaconda/lib/python2.7/site-packages/scrapy/templates/project', created in:

/Development/PetProjects/ScrapyCrawlers/olx

You can start your first spider with:

cd olx

scrapy genspider example example.com

创建Crawler

我运行了命令scrapy startproject olx,它将创建一个名为olx的项目以及后续步骤的有用信息。 您转到新创建的文件夹,然后执行命令以生成具有名称的第一个蜘蛛以及要爬网的站点的域:

在Python Scrapy中开发您的第一个Web爬虫_第3张图片

内容如下:

Adnans-MBP:ScrapyCrawlers AdnanAhmad$ cd olx/

Adnans-MBP:olx AdnanAhmad$ scrapy genspider electronics www.olx.com.pk

Created spider 'electronics' using template 'basic' in module:

olx.spiders.electronics

我使用名称electronics生成了我的第一个Spider的代码,因为我正在访问OLX的电子部分,我将它命名为,你可以将它命名为你想要的任何东西,或者将你的第一个蜘蛛献给你的配偶或(女孩|男孩)朋友:>

最终的项目结构将如下所示:

在Python Scrapy中开发您的第一个Web爬虫_第4张图片

Scrapy项目结构

如您所见,Spider有一个单独的文件夹,如上所述,您可以在一个项目中添加多个蜘蛛。 我们打开electronics.py蜘蛛文件。 当你打开它时,你会发现类似的东西:

在Python Scrapy中开发您的第一个Web爬虫_第5张图片

# -*- coding: utf-8 -*-

import scrapy

class ElectronicsSpider(scrapy.Spider):

name = "electronics"

allowed_domains = ["www.olx.com.pk"]

start_urls = ['http://www.olx.com.pk/']

def parse(self, response):

pass

如您所见,ElectronicsSpider是scrapy.Spider的子类。 name属性实际上是蜘蛛生成命令中给出的蜘蛛的名称。 运行爬虫本身时,此名称将有所帮助。 allowed_domains属性告知此爬网程序可以访问哪些域,并且strart_urls是提及首先要访问的初始URL的位置。 除了文件结构,这是绘制爬虫边界的一个很好的功能。

解析方法,顾名思义就是要解析被访问页面的内容。 由于我要编写一个可以访问多个页面的爬虫,我将进行一些更改。

from scrapy.spiders import CrawlSpider, Rule

from scrapy.linkextractors import LinkExtractor

class ElectronicsSpider(CrawlSpider):

name = "electronics"

allowed_domains = ["www.olx.com.pk"]

start_urls = [

'https://www.olx.com.pk/computers-accessories/',

'https://www.olx.com.pk/tv-video-audio/',

'https://www.olx.com.pk/games-entertainment/'

]

rules = (

Rule(LinkExtractor(allow=(), restrict_css=('.pageNextPrev',)),

callback="parse_item",

follow=True),)

def parse_item(self, response):

print('Processing..' + response.url)

为了使爬虫导航到许多页面,我宁愿从Crawler而不是scrapy.Spider继承我的Crawler。 此类可以更轻松地抓取网站的许多页面。 您可以使用生成的代码执行类似操作,但是您需要处理递归以导航下一页。

接下来是设置规则变量,这里提到导航网站的规则。 LinkExtractor实际上采用参数来绘制导航边界。 这里我使用restrict_css参数来设置NEXT页面的类。 如果你转到这个页面并检查元素你可以找到这样的东西:

在Python Scrapy中开发您的第一个Web爬虫_第6张图片

pageNextPrev是用于获取下一页链接的类。 call_back参数指示用于访问页面元素的方法。 我们很快就会研究这种方法。

请记住,您需要将方法的名称从parse()更改为parse_item()或其他任何内容以避免覆盖基类,否则即使设置了follow = True,您的规则也无法工作。

到目前为止一切顺利,让我们测试一下到目前为止我做过的爬虫。 再次,去终端并写:

Adnans-MBP:olx AdnanAhmad$ scrapy crawl electronics

第3个参数实际上是之前在ElectronicsSpiders类的name属性中设置的spider的名称。 在控制台上,您可以找到许多有助于调试爬虫的有用信息。 如果您不想查看调试信息,可以禁用调试器。 该命令与--nolog switch类似。

Adnans-MBP:olx AdnanAhmad$ scrapy crawl --nolog electronics

如果你现在运行它将打印如下:

Adnans-MBP:olx AdnanAhmad$ scrapy crawl --nolog electronics

Processing..https://www.olx.com.pk/computers-accessories/?page=2

Processing..https://www.olx.com.pk/tv-video-audio/?page=2

Processing..https://www.olx.com.pk/games-entertainment/?page=2

Processing..https://www.olx.com.pk/computers-accessories/

Processing..https://www.olx.com.pk/tv-video-audio/

Processing..https://www.olx.com.pk/games-entertainment/

Processing..https://www.olx.com.pk/computers-accessories/?page=3

Processing..https://www.olx.com.pk/tv-video-audio/?page=3

Processing..https://www.olx.com.pk/games-entertainment/?page=3

Processing..https://www.olx.com.pk/computers-accessories/?page=4

Processing..https://www.olx.com.pk/tv-video-audio/?page=4

Processing..https://www.olx.com.pk/games-entertainment/?page=4

Processing..https://www.olx.com.pk/computers-accessories/?page=5

Processing..https://www.olx.com.pk/tv-video-audio/?page=5

Processing..https://www.olx.com.pk/games-entertainment/?page=5

Processing..https://www.olx.com.pk/computers-accessories/?page=6

Processing..https://www.olx.com.pk/tv-video-audio/?page=6

Processing..https://www.olx.com.pk/games-entertainment/?page=6

Processing..https://www.olx.com.pk/computers-accessories/?page=7

Processing..https://www.olx.com.pk/tv-video-audio/?page=7

Processing..https://www.olx.com.pk/games-entertainment/?page=7

由于我设置了follow = True,爬虫将检查下一页的规则,并将继续导航,除非它到达规则不意味着的页面,通常是列表的最后一页。 现在想象一下,如果我要用这里提到的东西编写类似的逻辑,首先我必须编写代码来生成多个进程,我还必须编写代码来导航不仅下一页而且还限制我的脚本保持在边界中 不会访问不需要的URL,Scrapy从我的肩膀上消除了所有这些烦恼,让我专注于主要逻辑,即编写爬虫来提取信息。

现在我要编写代码,从列表页面中获取单个项目链接。 我将修改parse_item方法中的代码。

item_links = response.css('.large > .detailsLink::attr(href)').extract()

for a in item_links:

yield scrapy.Request(a, callback=self.parse_detail_page)

在这里,我使用.css响应方法获取链接。 正如我所说,你也可以使用xpath。 在这种情况下,它非常简单:

在Python Scrapy中开发您的第一个Web爬虫_第7张图片

锚链接有一个类detailsLink,如果我只使用response.css('。detailsLink'),那么由于重复img和h3标签中的链接,它将选择单个条目的重复链接。我做了什么,我也提到了父类,以获得独特的链接。我还使用:: attr(href)来提取链接本身的href部分。然后我使用extract()方法。使用的原因是.css和.xpath返回SelectorList对象,extract()有助于返回实际的DOM以供进一步处理。最后我在scrapy中产生了链接。回调。我没有检查Scrapy的内部代码,但很可能他们使用yield而不是return,因为你可以产生多个项目,因为爬虫需要一起处理多个链接,所以yield是这里的最佳选择。

名称告诉的parse_detail_page方法是从详细信息页面解析个别信息。那么实际发生的是:

您将获得parse_item中的条目列表

在回调方法中传递它们以进行进一步处理。

由于只有两级导线,我可以借助两种方法达到最低水平。如果我要从OLX的主页面开始爬行,我必须在这里编写3个方法;前两个用于获取子类别及其条目,最后一个用于解析实际信息。明白了吗?

最后,我将解析其中一个条目上可用的实际信息。

从这个页面解析信息并没有什么不同,但这里有一些东西要存储解析的信息。我们需要为我们的数据定义模型。这意味着我们需要告诉Scrapy我们想要存储哪些信息供以后使用。让我们编辑Scrapy先前生成的item.py文件。

import scrapy

class OlxItem(scrapy.Item):

# define the fields for your item here like:

# name = scrapy.Field()

pass

OlxItem是我将在其中设置保存信息所需字段的类。 我将为我的模型类定义3个字段。

class OlxItem(scrapy.Item):

# define the fields for your item here like:

title = scrapy.Field()

price = scrapy.Field()

url = scrapy.Field()

我将存储帖子的标题,价格和URL本身。 让我们回到crawler类并修改parse_detail_page。 现在一种方法是开始编写代码,通过运行整个爬虫进行测试,并确定你是否正确,但Scrapy提供了另一个很棒的工具。

Scrapy Shell

Scrapy Shell是一个命令行工具,为您提供测试解析代码的机会,而无需运行整个爬虫。 与转到所有链接的爬虫不同,Scrapy Shell会保存单个页面的DOM以进行数据提取。 在我的情况下,我做了以下:

Adnans-MBP:olx AdnanAhmad$ scrapy shell https://www.olx.com.pk/item/asus-eee-pc-atom-dual-core-4cpus-beautiful-laptops-fresh-stock-IDUVo6B.html#4001329891

现在我可以轻松地测试代码而无需一次又一次地访问相同的URL。 我通过这样做获取了标题:

In [8]: response.css('h1::text').extract()[0].strip()

Out[8]: u"Asus Eee PC Atom Dual-Core 4CPU's Beautiful Laptops fresh Stock"

你可以在这里找到熟悉的response.css。 由于整个DOM都可用,您可以使用它。

我通过这样做取价:

In [11]: response.css('.pricelabel > strong::text').extract()[0]

Out[11]: u'Rs 10,500'

由于response.url返回当前访问的URL,因此无需为获取url做任何事情。

现在检查所有代码,是时候将它合并到parse_detail_page中:

title = response.css('h1::text').extract()[0].strip()

price = response.css('.pricelabel > strong::text').extract()[0]

item = OlxItem()

item['title'] = title

item['price'] = price

item['url'] = response.url

yield item

解析所需信息后,正在创建OlxItem实例并正在设置属性。 到目前为止一直很好,现在是时候运行爬虫和存储信息了,命令略有修改:

scrapy crawl electronics -o data.csv -t csv

我正在传递文件名和文件格式以保存数据。 运行后,它将为您生成CSV。 容易,不是吗? 与您自己编写的爬虫不同,您必须编写自己的例程来保存数据,但等待! 它不会在这里结束,你甚至可以获得JSON格式的数据,你所要做的就是用-t开关传递json。

还有一件事,Scrapy为您提供了另一个功能,传递一个固定的文件名在现实场景中没有任何意义,我可以有一些工具来生成唯一的文件名吗? 好吧,为此您需要修改settings.py文件并添加以下两个条目:

FEED_URI = 'data/%(name)s/%(time)s.json'

FEED_FORMAT = 'json'

这里我给出了我文件的模式,%(name)%是爬虫本身的名称,时间是时间戳。 您可以在这里进一步了解它。 现在,当我运行scrapy crawl --nolog electronics或scrapy crawl electronics时,它会在数据文件夹中生成一个json文件,如下所示:

[

{"url": "https://www.olx.com.pk/item/acer-ultra-slim-gaming-laptop-with-amd-fx-processor-3gb-dedicated-IDUQ1k9.html", "price": "Rs 42,000", "title": "Acer Ultra Slim Gaming Laptop with AMD FX Processor 3GB Dedicated"},

{"url": "https://www.olx.com.pk/item/saw-machine-IDUYww5.html", "price": "Rs 80,000", "title": "Saw Machine"},

{"url": "https://www.olx.com.pk/item/laptop-hp-probook-6570b-core-i-5-3rd-gen-IDUYejF.html", "price": "Rs 22,000", "title": "Laptop HP Probook 6570b Core i 5 3rd Gen"},

{"url": "https://www.olx.com.pk/item/zong-4g-could-mifi-anlock-all-sim-supported-IDUYedh.html", "price": "Rs 4,000", "title": "Zong 4g could mifi anlock all Sim supported"},

在Python Scrapy中开发您的第一个Web爬虫_第8张图片

...

在Python Scrapy中开发您的第一个Web爬虫_第9张图片
在Python Scrapy中开发您的第一个Web爬虫_第10张图片

你可能感兴趣的:(在Python Scrapy中开发您的第一个Web爬虫)