学习爬虫开发的最好方法就是先有一个案例,然后由案例入手,抽丝剥茧,逐渐掌握爬虫技术的精髓。
下面使用Scrapy框架创建一个爬取百度热点新闻的案例,创建案例程序需要五个步骤:
(1) 使用Scrapy创建一个爬虫项目;
(2) 定义一个存储爬取数据的容器;
(3) 配置项目文件settings.py;
(4) 创建爬虫,编写代码;
(5) 运行爬虫程序。
使用Scrapy创建一个爬虫项目
在Windows命令行窗口,将存储项目文件的目录设置为当前目录,使用scrapy命令创建爬虫项目stock,项目名称可以是其它名称。
scrapy startproject stock
其中,scrapy是Scrapy框架提供的命令行程序,startproject是命令行程序的参数,该参数会创建一个新的爬虫项目,stock是项目名称。
该命令执行后,会在命令行窗口当前目录下创建stock目录,在stock目录存储了爬虫项目的相关文件。项目文件结构如下图所示:

※ spiders目录用于存储编写的爬虫业务逻辑代码;
※ item.py用于定义爬取数据的容器,item.py定义了一个类,该类可以定义要爬取数据的字段名称;
※ settings.py是项目的配置文件,用于设置项目的基础参数。如爬取数据的时间间隔、爬取时是否遵循 Robot 协议等;
※ pipelines.py用于对爬取的数据做进一步处理,如输出到json文件、mysql数据库等;
※ middlewares.py用于在scrapy爬取数据的流程中,开发者可以添加一些自定义的中间件,从而开发出适应不同情况的爬虫。
配置settings.py文件
settings.py是项目的配置文件,用于设置项目的基础参数。该配置文件可根据项目的需求随时更改配置项。
(1) 修改ROBOTSTXT_OBEY配置项
ROBOTSTXT_OBEY配置项用于配置爬虫是否遵循Robot 协议。在网站的根目录一般有 robots.txt 文件,该文件给出了允许爬虫爬取网页的范围,将该项设置为False,爬虫可以不受robots.txt 文件的约束。
ROBOTSTXT_OBEY = False
定义item容器
爬虫需要把爬取的数据存储到一个数据结构,item容器用来定义这样的数据结构。爬取网页之前,需要分析爬取网页的数据构成,在item.py文件定义与其对应的数据结构。
文件代码:
# 导入scrapy库
import scrapy
#自定义StockItem,用于存储爬虫所抓取的字段内容
class StockItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 新闻标题
news_title = scrapy.Field()
# 新闻链接
news_link = scrapy.Field()
代码定义了news_title、news_link 数据字段,news_title存储百度热点新闻的标题,news_link存储百度热点新闻的超链接,这些数据字段的类型是Field类。
创建爬虫,编写代码
爬虫代码的入口文件由scrapy命令创建,进入Windows命令行窗口,把项目目录设置为当前工作目录,输入下面的命令创建爬虫入口文件。
scrapy genspider spider_stockstar news.baidu.com
scrapy命令的genspider参数是创建一个爬虫,spider_stockstar是爬虫的名称,爬虫名称可以选择其它名称,news.baidu.com是要爬取网页路径,也就是起始URL,也可以是其它网页路径。
命令执行完成后,scrapy会在项目的spiders目录下创建spider_stockstar.py文件。
文件代码如下:
import scrapy
class SpiderStockstarSpider(scrapy.Spider):
name = 'spider_stockstar'
allowed_domains = [' news.baidu.com ']
start_urls = [' https://news.baidu.com/ ']
def parse(self, response):
pass
allowed_domains定义爬虫爬取的范围,爬取范围被限定在news.baidu.com域名下,start_urls定义爬虫要爬取的起始网页,案例中起始网页的内容是百度新闻的首页。
parse是网页内容解析函数,需要自己编写解析代码。
import scrapy
# 导入scrapy选择器
from scrapy.selector import Selector
# 导入StockItem
from stock.items import StockItem
class SpiderStockstarSpider(scrapy.Spider):
name = 'spider_stockstar'
allowed_domains = ['news.baidu.com']
start_urls = ['https://news.baidu.com/']
def parse(self, response):
# 爬取下来的HTML代码
html = response.text
# 使用xpath表达式搜寻指定的a标签节点,节点以列表方式返回
item_nodes = response.xpath("//div[@class='hotnews']/ul/li/strong/a").extract()
# 遍历节点
for item_node in item_nodes:
# 使用xpath表达式获取节点的href属性值
a_href = Selector(text=str(item_node)).xpath('//@href').extract()
# 使用xpath表达式获取节点的文本内容
a_text = Selector(text=str(item_node)).xpath('//text()').extract()
item = StockItem()
item["news_title"] = a_text
item["news_link"] = a_href
# 使用yield语句返回item给parse的调用者
yield item
运行爬虫程序
在项目的stock目录下,建立main.py文件,用于运行爬虫。
文件代码如下:
from scrapy.cmdline import execute
execute(["scrapy","crawl","spider_stockstar","-o","items.json"])
scrapy 的execute函数用于在Python程序启动spider_stockstar爬虫,并将爬取的数据存储到items.json文件。函数的执行类似于在Windows命令行窗口执行下面的命令:
scrapy crawl spider_stockstar -o items.json
爬虫运行后,爬虫会把爬取的内容以JSON数据格式存储到项目的stock目录,JSON文件名称为items.json。