下面是我为你提供的详细攻略:
一步步教你用python的Scrapy编写一个爬虫
Scrapy是Python的一个高效的爬虫框架,可以帮助我们快速、简单地构建爬虫程序。在本攻略中,我们介绍如何使用Scrapy编写一个简单的爬虫程序。
安装Scrapy
在开始编写爬虫之前,我们需要先安装Scrapy。在终端(命令行)中输入以下命令来安装Scrapy:
pip install scrapy
创建一个Scrapy项目
创建Scrapy项目的命令是:
scrapy startproject project_name
其中,project_name是你的项目名称,可以自定义。执行完这个命令后,会在当前目录下创建一个名为project_name的项目目录以及一些必要的文件:
project_name/
scrapy.cfg # Scrapy配置文件
project_name/ # 项目目录
__init__.py
items.py # 定义爬虫数据模型
middlewares.py # 定义爬虫中间件
pipelines.py # 定义爬虫管道
settings.py # Scrapy配置设置文件
spiders/ # 放置爬虫代码
__init__.py
定义爬虫
Scrapy的爬虫模块是通过Spider类来实现的。在爬虫的回调函数中,我们编写代码来解析网页内容,并将数据保存到items中。以下是一个示例:
import scrapy
from myproject.items import MyItem
class MySpider(scrapy.Spider):
name = 'myspider'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com']
def parse(self, response):
item = MyItem()
item['title'] = response.xpath('//title/text()').extract()[0]
item['text'] = response.xpath('//p/text()').extract()
return item
在爬虫中,我们定义了爬虫的名称(name)、允许抓取的域名(allowed_domains)、爬虫起始URL(start_urls)以及解析网页的回调函数(parse)。在回调函数中,我们使用XPath选择器来解析网页内容,并将提取到的数据保存到item中。
定义Item
我们需要在项目的items.py
文件中定义数据模型,以便在爬虫中保存数据。以下是一个示例:
import scrapy
class MyItem(scrapy.Item):
title = scrapy.Field()
text = scrapy.Field()
在MyItem
中,我们定义了两个属性:title和text。这两个属性的值在爬虫中被填充,然后保存到该Item对象中。
定义管道
管道是Scrapy的一个组件,用于处理爬虫提取到的数据。我们可以定义一个或多个管道,用于处理数据的清洗、保存到数据库等操作。以下是一个示例:
class MyPipeline():
def process_item(self, item, spider):
# 在此处处理爬虫提取到的数据
return item
在这个管道中,我们编写了一个process_item
方法,用于处理爬虫提取到的数据。在该方法中,我们可以对数据进行清洗、去重,或者将数据保存到数据库中等操作。
运行爬虫
接下来,我们需要运行爬虫了。在终端(命令行)中输入以下命令来运行爬虫:
scrapy crawl myspider
其中,myspider
是你定义的爬虫名字。Scrapy会从爬虫类中找到该名字相应的Spider
类,并启动爬虫。
到此,我们已经完成了用Scrapy编写一个爬虫的过程。如果你想深入了解Scrapy的更多细节,请阅读Scrapy的文档。
示例1:爬取豆瓣Top250电影信息
下面,让我们来看一个示例,它能够爬取豆瓣Top250电影的信息。在示例里,我们使用了XPath选择器来解析HTML内容。
首先,在命令行中使用scrapy startproject
命令创建一个Scrapy项目,然后进入到项目目录中,在命令行中输入以下命令来创建一个新的爬虫:
scrapy genspider doubanmovie movie.douban.com
在爬虫类中,我们首先定义了起始的URL,然后在parse
回调函数中,通过XPath选择器解析出每部电影的名称、导演、主演、评分等信息,并将其保存为MovieItem
对象。接着,我们将每个电影的详情页面的URL加入到request队列中,并通过回调函数parse_movie_detail
继续处理电影的详细信息。
import scrapy
from scrapy import Request
from doubanmovie.items import MovieItem
class DoubanmovieSpider(scrapy.Spider):
name = 'doubanmovie'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250']
def parse(self, response):
for movie in response.xpath('//ol[@class="grid_view"]/li'):
item = MovieItem()
item['name'] = movie.xpath('.//h2/a/text()').extract_first()
item['director'] = movie.xpath('.//div[@class="bd"]/p[1]/text()').extract()
item['star'] = movie.xpath('.//div[@class="star"]/span[@class="rating_num"]/text()').extract()
item['link'] = movie.xpath('.//div[@class="pic"]/a/@href').extract()
yield Request(item['link'], callback=self.parse_movie_detail, meta={'item': item})
def parse_movie_detail(self, response):
item = response.meta['item']
item['genres'] = response.xpath('//span[contains(text(),"类型")]/following-sibling::text()[1]').extract()
actors = response.xpath('//span[contains(text(),"主演")]/following-sibling::a/text()').extract()
item['actors'] = [actor.strip() for actor in actors]
item['summary'] = response.xpath('//span[contains(text(),"简介")]/following-sibling::span/text()').extract_first().strip()
yield item
接着,我们在items.py
中定义数据模型MovieItem
:
import scrapy
class MovieItem(scrapy.Item):
name = scrapy.Field()
director = scrapy.Field()
star = scrapy.Field()
link = scrapy.Field()
genres = scrapy.Field()
actors = scrapy.Field()
summary = scrapy.Field()
最后,我们还需要将数据保存到JSON文件中,可以在Scrapy配置文件settings.py
中指定输出文件的路径和记录格式:
FEED_URI = 'movies.json'
FEED_FORMAT = 'json'
示例2:爬取机器学习论文信息
以下是一个更为复杂的示例,它能够爬取机器学习领域的论文信息。这个爬虫需要定制化处理数据清洗、记录去重等问题,同时涉及多个页面的抓取和分页处理。
首先,在命令行中使用scrapy startproject
命令创建一个Scrapy项目,然后进入到项目目录中,创建一个新的爬虫:
scrapy genspider arxiv arxiv.org
在爬虫类中,我们首先定义了起始的URL,同时通过指定headers
来扮演谷歌浏览器的角色。为了爬取所有可用的页面,我们在start_requests
函数中使用了循环来生成所有的查询URL。在parse
回调函数中,我们使用XPath选择器解析出每篇论文的作者、标题、摘要等信息,并将其保存为PaperItem
对象。接着,我们检查数据库中是否已有记录,有则去重,没有则将记录加入到数据库中。最后,我们还需要构造下一页的请求,并通过回调函数parse
继续爬取下一页的数据。
import scrapy
from scrapy import Request
from arxiv.items import PaperItem
import pymongo
class ArxivSpider(scrapy.Spider):
name = 'arxiv'
allowed_domains = ['arxiv.org']
start_url_template = 'https://arxiv.org/search/advanced?advanced=&terms-0-operator=AND&terms-0-term={}&terms-0-field=title&classification-physics_archives=all&classification-qc_archives=all&classification-conn_archives=all&classification-astrophysics_archives=all&date-filter_by=all_dates&date-year=&date-from_date=&date-to_date=&date-date_type=submitted_date&abstracts=show&size=50&order=-announced_date_first'
def start_requests(self):
keywords = ['machine+learning', 'deep+learning', 'neural+network']
for kw in keywords:
yield Request(self.start_url_template.format(kw), headers={'User-Agent': 'Mozilla/5.0'})
def parse(self, response):
client = pymongo.MongoClient('mongodb://localhost:27017/')
db = client['arxiv']
papers = db['papers']
for paper in response.xpath('//li[@class="arxiv-result"]'):
item = PaperItem()
item['title'] = paper.xpath('.//p[@class="title is-5 mathjax"]/a/text()').extract()
item['authors'] = paper.xpath('.//span[contains(text(), "Authors")]/following-sibling::a/text()').extract()
item['abstract'] = paper.xpath('.//p[contains(text(), "Abstract")]/following-sibling::p/text()').extract()
item['link'] = paper.xpath('.//a[contains(text(), "PDF")]/@href').extract()
if item['link']:
item['link'] = item['link'][0]
else:
item['link'] = ''
# 去重处理
if papers.find_one({'link': item['link']}):
continue
else:
papers.insert_one(dict(item))
yield item
# 翻页处理
if response.xpath('//li[@class="next"]/a/@href'):
next_url = 'https://arxiv.org' + response.xpath('//li[@class="next"]/a/@href')[0]
yield Request(next_url, headers={'User-Agent': 'Mozilla/5.0'})
在items.py
中,我们定义了数据模型PaperItem
,用于保存论文的作者、标题、摘要和链接等信息。
import scrapy
class PaperItem(scrapy.Item):
authors = scrapy.Field()
title = scrapy.Field()
abstract = scrapy.Field()
link = scrapy.Field()
最后,我们还需要将数据保存到MongoDB数据库中,可以在Scrapy配置文件settings.py
中指定数据库的连接参数和保存的集合名称:
MONGODB_SERVER = 'localhost'
MONGODB_PORT = 27017
MONGODB_DB = 'arxiv'
MONGODB_COLLECTION = 'papers'
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一步步教你用python的scrapy编写一个爬虫 - Python技术站