之前的文章是爬虫糗事百科并插入到MySQL数据库,使用的是BeautifulSoup解析静态网页,select(返回列表)、find_all(返回列表)和find(返回单个结果)以及正则定位获取网页数据,pymysql链接插入本地MySQL数据库。为了扩展自己的爬虫技能,今天的代码是爬虫异步加载的简书首页文章,使用的是lxml解析网页,XPath定位获取网页数据,以及pymongo链接插入本地Mongo数据库(之前不懂MongoDB,看到很多人都使用Mongo数据库存储爬虫数据,特别学习了一下,感觉这个非关系型数据库还是很好用的)。爬取的首页文章数据包括:标题,作者,发表时间,阅读量,评论数,点赞数,打赏数,所投专题,代码的完成参考了loading_miracle的文章,他的文章思路清晰,图文并茂,很适合学习!下面是程序代码,每一句都加了注释说明,方便整理思路,代码的写法存在许多不规范的地方,还请大家留言指教,谢谢。
import requests
from lxml import etree
#import re
import pymongo
#构建爬取简书首页的类
class JianshuSpider(object):
#链接Mongo数据库
client = pymongo.MongoClient('localhost', 27017)
#创建数据库 mydb (应该叫连接数据库,比较创建数据库更合适)
mydb = client['mydb']
#创建数据表 jianshu
jianshu = mydb['jianshu']
#请求头
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
}
#创建一个数组,用以存储文章的id,作为异步加载的请求参数
params = []
#Class的构造函数(我习惯这么称呼它)
def __init__(self):
pass
#获取异步加载的url的函数(15页),并请求数据
def totalpage(self):
for i in range(0,15):
data = '&'.join(self.params)
url = 'http://www.jianshu.com/?' + data + '&page={}'.format(i)
self.get_data(url)
#爬取数据,并插入Mongo数据库的函数
def get_data(self,url):
#模拟浏览器访问网页
html = requests.get(url,self.headers).text
#etree.HTML解析网页内容返回给respone
response = etree.HTML(html)
#获取请求文章的ID并存入数组并作为请求携带参数
ids = response.xpath('//*[@id="list-container"]/ul/li')
for one in ids:
one = 'seen_snote_ids[]=' + one.xpath('@data-note-id')[0]
self.params.append(one)
#xpath得到所有包含目标内容的div的集合
div_list = response.xpath('//*[@id="list-container"]/ul/li/div')
#for循环分别读取d集合中的目标数据
for div in div_list:
#定位获取文章标题数据-->text()
title = div.xpath('a/text()')[0]
#定位获取作者名字数据-->text()
author = div.xpath('div[1]/div/a/text()')[0]
#定位获取发表时间数据-->非文本text()而是属性@
release_time = div.xpath('div[1]/div/span/@data-shared-at')[0]
#定位获取文章阅读量(用XPath无法定位获取数据)
#reading_num = div.xpath('div[2]/a[2]/text()')[0]
#定位获取文章评论数(用XPath无法定位获取数据)
#comment_num = div.xpath('div[2]/a[3]/text()')
#定位获取点赞数量
like_num = div.xpath('div[2]/span/text()')[0]
#打赏数和所投专题可能为None,顾需特别处理
#判断所投专题
flg1 = div.xpath('div[2]/a[1]/text()')[0]
topic = div.xpath('div[2]/a[1]/text()')[0] if flg1!=None else ""
#判断打赏数
flg2 = div.xpath('div[2]/span[2]/text()')
play_num = div.xpath('div[2]/span[2]/text()')[0] if len(flg2)>0 else 0
#爬取数据后,构建数据字典
data = {
'标题':title,
'作者':author,
'发布时间':release_time,
#'阅读数':reading_num,
#'评论数':comment_num,
'点赞数':like_num,
'所投专题':topic,
'打赏数':play_num
}
#向数据库插入数据
self.jianshu.insert_one(data)
if __name__ == '__main__':
#初始化简书爬虫这个类
jssy_spider = JianshuSpider()
#调用简书爬虫类的totalpage()函数
jssy_spider.totalpage()
插入MongDB效果:
除文章的阅读数和评论数没有爬到,其他都插入到Mongo数据库中了,很奇怪不知道为什么用XPath无法定位获取这两类数据,尝试参照loading_miracle的文章改用正则表达式获取,但是发现自己使用正则获取数据后,分页异步加载的数据不正确。第一次使用XPath,很多定位技巧都不掌握,还请大神帮忙解决用XPath定位这两类数据。