作者:邓旭东HIT
打开知乎Live网址
https://www.zhihu.com/lives
打开浏览器开发者工具(F12)
我们直接拖动页面向下滚动,Network中就出现了很多网址和数据。 其中如下图的网址
数据与网页直播的title对应上了。说明找到了对应的网址。而且这数据还是json格式,使用起来特别方便。
网址如下
https://api.zhihu.com/lives/homefeed?limit=10&offset={offset}&includes=live
只需要更改offset即可请求相应网址对应live信息
为了节约时间,今天我就只爬live标题和演讲者。
打开终端命令行输入
- scrapy startproject livespider[项目存放的文件夹的路径]
我在桌面上首先新建了一个scrapysqlite文件夹,然后才在终端创建livespider,项目存放于scrapysqlite文件夹中
.png” />
现在我们用Pycharm打开livespider项目
现在我们看下打开后的文件目录
上图打开的项目目录,都是scrapy startproject livespider这个命令行回车后自动生成的。
文件或文件夹功能spiders文件夹是用来存放爬虫逻辑的文件夹items.pyspider文件夹中的爬虫脚本解析的数据,通过items.py组织数据形式pipelines.py爬虫解析出的数据,通过items封装后传递给管道,流到数据库或数据文件。pipelines实际上就是配置数据库或数据文件的settings.py整个爬虫项目的配置文件middleware.py一般不怎么用,忽略。
我们要在spiders文件夹里创建一个zhihu.py 爬虫(spider)。我们可以通过点击Pycharm下方的Terminal,输入
- scrapy genspider zhihu zhihu.com
生成zhihu.py文件,爬虫允许爬的域名为http://zhihu.com。
现在我们要开始对项目进行全局配置。 打开settings.py文件,将
- ROBOTSTXT_OBEY = True
- 改为(不遵守机器人协议,方便爬取数据)
- ROBOTSTXT_OBEY = False
取消DOWNLOAD_DELAY的注释符#,并赋值为1。 此处为限制爬虫的访问网站速度。
取消DEFAULTREQUESTHEADERS的注释,并填写zhihu页面解析时的headers请求头
这里注意,经过测试发现,如果没有Authorization,只有useragent,是无法正常访问知乎网站的。所以自己查找并填写。
取消ITEM_PIPELINES的注释符#
因为今天为了省事,我们就只爬知乎Live的标题和演讲者。
items.py功能相当于爬虫解析出的数据需要一个结构化的容器封装,方便传递给pipelines使用。
形象一点的比喻就是,items将数据打包,方便运输。本项目中的zhihu.py爬虫将网站中得到的数据通过items的形式打包数据,传递给pipelines水管,并将数据流入数据库保存。
打开items.py文件,将文件修改为
- from scrapy import Field,Item
- class LivespiderItem(Item):
- # define the fields for your item here like:
- # name = scrapy.Field()
- title = Field()
- speaker = Field()
现在开始我们先创建好数据库,然后在配置pipelines.py Pycharm实际上可以可视化操作sqlite。
然后依次点击2、3
2. sqlite数据库要能在Pycharm中第一次使用,需要先安装驱动。
图中底部红线指示,点击Download即可
选择scrapy创建好的livespider项目路径,并将数据库命名为zhihulive.db ,点击apply和ok
按照图中的123,依次点击Database 、zhihulive.db 、main
点击图中红框,先设置Table表名为LiveTable。 点击加号,依次设置了id为主键整数型自增序号。title和speaker均为TEXT格式数据
创建好数据库和表,后面我们就要在pipeline.py中操作数据。
打开pipelines.py你会看到如下默认代码
import sqlite3
class LivespiderPipeline(object): def process_item(self, item, spider): pass
我们应该首先知道,pipelines是为了将数据存入数据的。
依次对应的scrapy默认的功能函数为
- def open_spider(self,spider):
- pass
- def process_item(self, item, spider):
- #写入数据库或数据文件
- return item
- def close(self,spider):
- #关闭数据库
- pass
根据上面的知识,我们完成了下面的pipelines.py 的配置。注意format传递值的时候,前面的变量是要用 ‘{}’。
- import sqlite3
- class LivespiderPipeline(object):
- def open_spider(self,spider):
- #初始化爬虫,开启数据库或者新建一个csv文件
- self.con = sqlite3.connect('zhihulive.db')
- self.cur = self.con.cursor()
- def process_item(self, item, spider):
- #写入数据库或数据文件
- title = item['title']
- speaker = item['speaker']
- sql_command = "INSERT INTO LiveTable (title,speaker) VALUES ('{title}','{speaker}')".format(title=title, speaker=speaker)
- self.cur.execute(sql_command)
- self.con.commit() return item
- def close_spider(self,spider): #关闭数据库或者数据文件
- self.con.close()
前面所有的准备都是为了这一刻,我们能够将爬到的数据存起来。现在我们开始爬虫的逻辑,也是最关键的部分。spiders文件夹下的zhihu.py
在ZhihuSpider类中,scrapy框架有默认的请求函数start_requests ,该函数对网址发起请求,yield方式返回的相应数据传递给该ZhihuSpider类中的parse函数解析。
callback是回调,也就是说start_requests得到的网页数据要传输给parse函数解析。
- def start_requests(self):
- starturl = 'https://api.zhihu.com/lives/homefeed?limit=10&offset=10&includes=live'
- yield Request(url=starturl, callback=self.parse)
parse函数负责解析数据,将数据以item形式封装,并以yield方式传输给pipelines,最终写入数据库。
yield其实很像return,只不过,return后会结束函数。而yield的函数相当于生成器,返回结果后并不直接结束函数,而是保留状态,下次运行函数会按照上次的位置继续迭代下去。
- from scrapy import Spider,Request
- from livespider.items import LivespiderItem
- import json
- class ZhihuSpider(Spider):
- name = 'zhihu'
- allowed_domains = ['zhihu.com']
- start_urls = ['http://zhihu.com/']
- def start_requests(self):
- starturl = 'https://api.zhihu.com/lives/homefeed?limit=10&offset=10&includes=live'
- yield Request(url=starturl, callback=self.parse)
- def parse(self, response):
- item = LivespiderItem()
- result = json.loads(response.text)
- records = result['data']
- for record in records:
- item['title'] = record['live']['subject']
- item['speaker'] = record['live']['speaker']['member']['name']
- #将item传给pipelines.py保存到数据库
- yield item
- next_page_url = result['paging']['next']+'&includes=live'
- yield Request(url=next_page_url, callback=self.parse)
全部写好了。现在在Pycharm终端Terminal中输入
scrapy crawl zhihu
开始愉悦的爬数据,而且还能用Pycharm看到数据库中的数据
这部分写的很粗糙,不懂的可以反复看我的视频。
End.
来源: http://www.36dsj.com/archives/98031