适用于像我一样的python入门级选手服用,如果已经使用Scrapy框架至少一次成功获取到网页数据,不必在此浪费时间。当然对小白来讲可能理解起来相对容易。
框架简介
- python开发的一个为了抓取网页数据、提取结构性数据的快速、高层次的抓取框架。由于封装了如requests库,下载器等等东西,灵活性不足。
- 效率是真的很高。曾经试图单纯使用requests库爬取某网站共80页15条7项数据,运行一遍1小时起步(我也不知道他为什么这么慢)。但是借助框架5分钟左右。(忽然想起来是不是电脑配置不太行)。
- 包含很多组件:引擎(Scrapy),下载器(Downloader)、调度器(Scheduler)、爬虫(Spider)、项目管道(Piplines)、中间件(Middlewares)如下载器中间件、爬虫中间件、调度中间件等。
- ?一个简单的Scrapy 框架结构。其中
spiders目录下是主要干活的部分。例如自定义爬虫文件example,将从特定的网页中提取目标数据,形成实体;
items文件随工程的建立生成,用户在其中定义实体的数据;
执行文件main中的方法即执行该工程,是通过命令行执行的替代,该文件由用户自定义生成;
piplines负责处理爬虫从网页中提取的实体,主要功能是持久化实体,简单形式如存储数据到Excel、数据库等;
settings文件中可以设置诸如管道的开闭、是否遵循robots协议、用户代理等内容,也可以定义一些常量增强代码可维护性;
Windows下安装
- 我用anaconda,可能是先前安装时少下了什么东西,导致在其他电脑上能奏效的安装方法在我这总是缺了些什么,缺了就查攻略,有没有用都靠缘分。
- 我的建议是,先pip install Scrapy看缺什么,再给他补什么。一般情况下pywin32似乎必需
- 我自己安装过的东西:
win32api
.framework
twisted
wheel
incremental(这个东西我用pip list检查显示是有的但是报这个错,所以我重装了)
基本步骤
以智*招聘的岗位信息为例
建一个工程
- pycharm中在显示执行结果的区域有一个名为Terminal的选项卡,我的Spyder没有就cmd,输入scrapy startproject zhaopin(工程名),将直接在当前目录下建立一个名为zhaopin的工程,因此注意路径
此时该工程文件结构为:
- 创建爬虫应用。运行scrapy genspider zhaopin(爬虫名) zhaopin.com(域名) 命令在spiders目录下新建一个爬虫应用。
注意:爬虫名不能与工程名一致
- 运行爬虫应用。其一,采用dos命令,执行scrapy crawl zhaopin(爬虫应用名);其二,创建.py文件引入cmdline,执行该文件达到运行目的。
main.py中的内容:
#scrapy crawl 应用名称:日志的形式运行爬虫应用 --nolog取消日志
from scrapy import cmdline
cmdline.execute("scrapy crawl zhaopin --nolog".split())
至此一个采用scrapy框架爬虫的工程文件结构基本成型,接下来便是具体实现
实现
- items
import scrapy
class ZhaopinItem(scrapy.Item):
jobname = scrapy.Field()
companyname = scrapy.Field()
- spiders
import scrapy
import json
from zhaopin_pro.items import ZhaopinProItem
class ZhaopinSpider(scrapy.Spider):
name = 'zhaopin' #爬虫名,一般与文件名相同,不允许重复,按照文件名爬虫
allowed_domains = ['zhaopin.com','fe-api.zhaopin.com'] #限制域名,起始路径中不包含允许域名则不允许爬虫
start_urls = ['https://fe-api.zhaopin.com/c/i/sou?&pageSize=90&cityId=854&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=java&kt=3&_v=0.46880996&x-zp-page-request-id=2c5e1c1b0a3f448996ce61acf87be46d-1562292190264-205445&x-zp-client-id=5eaebb71-95e9-426d-8b07-7315576a86e7']
#默认调用当前方法,请求页面并返回结果
def parse(self, response):
#print(type(response)) #<class 'scrapy.http.response.text.TextResponse'>
json_data=json.loads(response.text)
jobs = json_data['data']['results']
for job in jobs:
#每运行一次获得一个实体对象
item=ZhaopinProItem()
#给实体对象赋值
item['jobname'] = job['jobName']
item['companyname'] = job['company']['name']
#把信息传给引擎,引擎传给项目管道piplines
yield item
#针对html数据的获取方式,举个例子
def parse(self, response):
div_list = response.xpath('..//div[@id="comments"]/div[@class="comment-item"]')
for div in div_list:
coms = div.xpath('div[@class="comment"]/p/span[@class="short"]/text()')[0].extract()
item=DoubanItem()
item['coms']=coms
yield item
- piplines
import xlwt
#以存储到Excel中为例
class ZhaopinProPipeline(object):
def __init__(self): #初始化方法
self.workbook=xlwt.Workbook(encoding="utf8")
# Spider开启时调用,默认调用
def open_spider(self, spider):
self.sheetlist=self.workbook.add_sheet("基本信息",True)
self.rowlist=0
def process_item(self, item, spider):
self.sheetlist.write(self.rowlist, 0, item['jobname'])
self.sheetlist.write(self.rowlist, 1, item['companyname'])
self.rowlist+=1 #控制存储行数
return item
# Spider关闭时调用
def close_spider(self, spider):
self.workbook.save("zhaopin.xls")
- settings
#settings.py中依据程序功能的要求去掉相应部分的注释,打开相应模块
运行结果
其他
一个很神奇的问题:尽管main方法中的语句正确而且爬虫应用名与spiders中新建文件的name属性一致,但是执行时总是报错:
然而dos命令中键入scrapy crawl zhaopin却可以正常执行
……疑惑
补充:上述问题原因在于在main.py中from Scrapy import cmdline,执行时总是默认从lib/site_package找被执行文件,因此not found。在pycharm中可以通过Mark Directory as Sources Root解决,Spyder我还没有找到解决方法……