scrapy爬虫实用模版例程&一些规则
一个临时scrapy任务,可以实现基本的数据爬虫,根据需要自行增添爬取网页内容的模版,有空再完善pipline等更高级的功能。
源代码和爬房价的代码上传:https://github.com/ming71/scapy
目录
一个例子
爬取http://books.toscrape.com,网页50页,每页20本书,共1000本书的价格和名字,了解scrapy爬虫编写的一般步骤。
-
创建项目
打开终端,在目标文件夹下运行:
scrapy startproject example
自动创建工程文档,文件结构如下(tree example树形查看):
example
├── example
│ ├── __init__.py
│ ├── items.py
│ ├── middlewares.py
│ ├── pipelines.py
│ ├── __pycache__
│ ├── settings.py
│ └── spiders
│ ├── __init__.py
│ └── __pycache__
└── scrapy.cfg
下面说明部分可以改的文件:
items.py : 用于自定义数据类,封装爬取的数据
pipelines.py:管道设置,与item连用
settings.py:设置文件
spiders : 该文件夹下后面需要手动创建一个spider爬虫程序主体
-
分析目标网页
Chorm浏览器为例,进入网页http://books.toscrape.com,在想要审查元素的地方右键鼠标,选择检查,即可定位到html的指定位置。从而获得网页和代码的对应关系。如下图,找到第二本书的名字:
-
实现spider
分析完页面后,接下来编写爬虫。在Scrapy中编写一个爬虫,即实现一个scrapy.Spider的子类。实现爬虫的Python文件应位于exmaple/spiders目录下,在该目录下创建新文件book_spider.py。然后,在book_spider.py中实现爬虫BooksSpider,代码如下:
# -*- coding: utf-8 -*-
import scrapy
class BooksSpider(scrapy.Spider):
name = "books" # 每一个爬虫的唯一标识
start_urls = ['http://books.toscrape.com/'] # 定义爬虫爬取的起始点,起始点可以是多个,这里只有一个
def parse(self, response):
# 提取数据
# 每一本书的信息在<article class="product_pod">中,使用css()方法找到所有这样的article元素,并依次迭代
# 语法也可选择xpath
for book in response.css('article.product_pod'):
# 书名信息在article > h3 > a 元素的title属性里
# 例如: <a title="A Light in the Attic">A Light in the ..
name = book.xpath('./h3/a/@title').extract_first()
# 书价信息在 <p class="price_color">的TEXT中。
# 例如: <p class="price_color">£51.77</p>
price = book.css('p.price_color::text').extract_first()
yield {
'name': name,
'price': price,
}
# 提取翻页链接
# 下一页的url 在ul.pager > li.next > a 里面
# 例如: <li class="next"><a href="catalogue/page-2.html">next
next_url = response.css('ul.pager li.next a::attr(href)').extract_first()
if next_url:
# 如果找到下一页的URL,得到绝对路径,构造新的Request 对象
next_url = response.urljoin(next_url)
yield scrapy.Request(next_url, callback=self.parse)
子类中有三个重要元素:
● name属性
一个Scrapy项目中可能有多个爬虫,每个爬虫的name属性是其自身的唯一标识,在一个项目中不能有同名的爬虫,此处爬虫取名为'books'。
● start_urls属性
start_urls属性用来设置一个爬虫的起始爬取点,也可以在list中设置多个起始点。
● parse方法
当一个页面下载完成后,Scrapy引擎默认调用parse方法解析页面(parse方法为主要自定义部分)。一个页面解析函数通常需要完成以下两个任务:提取页面中的数据(使用XPath或CSS选择器)。提取页面中的链接,并产生对链接页面的下载请求(next_url)。
难点在解析和提取网页内容,后面分析。
-
运行和数据存储
运行下面语句即可,其中books是自定义爬虫的name属性:
scrapy crawl books
如果需要输出可以:
scrapy crawl books -o books.csv #还可以为json文件
爬取结果:
例子分析
上面的例子作为模版,用于简单爬取网页信息已经足够,但是自己拿来用还需要了解更多语法和知识。https://newhouse.fang.com/house/s/以爬取房价和房源地点为例,自己写一个爬虫练习。
模版同上,只用修改spider程序的部分,涉及两个问题:
怎么提取数据?怎么提交next请求?
我理解的就是在页面中通过遍历寻找和房源地点相关的特征属性,然后提取其中的数据,方法有css()和xpath(),需要学习部分关于其的语法,以xpath()为主就行,两者是一样的。ps:还可以通过html代码页面待提取位置右键->copy->copy xpath进行参考
xpath的语法及例子参考如下:https://www.jianshu.com/p/2391950137a4,http://python.jobbole.com/84689/
至于下一个页面的请求,可以使用模版语句,只需要寻找到页面的next按钮(下一页)的url即可。但是经过实践发现。该页面为动态js,无法通过url简单访问。解决办法比较麻烦,没时间去找,技术问题可以通过技巧解决:该网站有21页,通过不同页的url改变规则,发现url的导数二三位对应页码,通过for循环遍历21页,创建21个不同的URL进行访问爬取即可~代码如下:
class BooksSpider(scrapy.Spider):
name = "books"
start_urls = ['https://newhouse.fang.com/house/s/']
def parse(self, response):
for i in range (1,22):
next_url = 'https://newhouse.fang.com/house/s/b9'+str(i)+'/'
# print(next_url)
# a=input()
for book in response.css('div.nlc_details'):
name = book.xpath('.//div[@class="address"]/a/@title').extract_first()
price = book.xpath('.//div[@class="nhouse_price"]/span/text()').extract_first()
unit = book.xpath('.//div[@class="nhouse_price"]/em/text()').extract_first()
yield {
'name': name,
'price': price,
'单位': unit
}
next_url = response.urljoin(next_url)
yield scrapy.Request(next_url, callback=self.parse)
然后爬虫输出数据(房源地址+价格+单位)就行,得到爬取结果如下:
这个网页也写的比较清楚,有空要在学习可以看一下:https://blog.****.net/qq_40134903/article/details/80548607