python爬虫中的mongo实践

来源:互联网 发布:淘宝宝贝怎么上架 编辑:程序博客网 时间:2024/06/12 19:05

目标

  1. 获取全本小说网的小说封面
  2. 保存封面图片到mongo数据库中
  3. 记录封面图片对应的小说信息

分析

  1. 本次使用requests作为http请求工具
  2. 获取小说封面的方式采用爬虫分类型、分页爬去小说封面地址
  3. 向图片的原地址发送http的get请求,获取response的content就是图片的二进制数据了
  4. 本次存储图片的方式并采用系统自带的文件系统,而是使用mongodb的GridFS
  5. 将步骤3中的content数据put到gridfs中获取文件id
  6. 从步骤2中获取小说的名称等信息,与步骤5中的id做映射,保存到novel集合集中
    注:步骤6在是可以将小说的其他信息一同保存至gridfs的files集合中的,使用方法会在代码中进行注释

示例

import requestsfrom bs4 import BeautifulSoupimport pymongoimport gridfsimport time# 获取mongoClient对象client = pymongo.MongoClient("localhost", 27017)# 获取使用的database对象db = client.test# 获取图片存储集合fs = gridfs.GridFS(db, "images")def save_pic_to_disk():    """    将数据库中文件转存到本地文件系统    :return: 无    """    fss = fs.find()    for fl in fss:        print(fl.md5)        tp_file = open('d:/img/' + fl.md5 + '.jpg', "wb")        tp_file.write(fl.read())        tp_file.close()def mongodb_delete(title, author):    """    根据小说标题和作者删除其小说封面信息    例如:mongodb_delete('桃花扇','孔尚任')    :param title 小说标题    :param author 小说作者    """    record = db.novel.find_one({"title": title, "author": author})    print(record)    _id = record.get("_id")    _img = record.get("imag")    db.novel.remove({"_id": _id})    fs.delete(_img)def iterator(url):    """    遍历指定地址下的小说条目    获取小说封面、标题和作者信息    然后保存至数据库    最后获取递归到下一页进行遍历    :param url: 小说列表页面地址    :return: 无返回    """    print(url)    # 获取页面html,并使用beautifulsoup进行解析    rs = requests.get(url).content.decode("gbk")    bs_obj = BeautifulSoup(rs, "html.parser")    content = bs_obj.find("div", {"id": "content"})    # 获取小说列表,并遍历小说数据    novels = bs_obj.findAll("div", {"class": "Sum Search_line"})    for novel in novels:        # 获取小说的名称、索引地址、作者        name = novel.find("h2").find("a").get_text()        index = novel.find("h2").find("a").get("href")        author = novel.find("em").find("a").get_text()        # 获取小说封面,并使用gridfs保存至mongo        img = novel.find("img")        rs = requests.get(img.get("src"))        # 这种方式是将小说的题目等信息与封面图片保存在一起        # fs.put(rs.content,title=name, author=author, url=index)        # 这种方式进行保存图片文件,然后记录文件编号,比较像关系数据库的使用方式        _id = fs.put(rs.content)        db.novel.save(dict(title=name, author=author, url=index, imag=_id, time=time.time()))    # 获取下一页链接,如果存在下一页就进行递归遍历    next_page = content.find("div", {"id": "pagelink"}).find("a", {"class": "next"})    if next_page:        iterator(next_page.get("href"))# 遍历全本小说网的小说信息# 从小说站点的导航上可以看出,该站点小说分为11个类型,而且类型编号从1开始递增for i in range(1, 12):    iterator('http://www.wanbenxiaoshuo.net/sort/' + str(i) + '_1.html')# 关闭资源client.close()

总结

  • pymongo的简单使用

在上述代码中使用pymongo作为python操作mongodb的工具,除了完成目标要求,还额外书写了两个方法用于体验pymongo的使用。总结一下pymongo的简单使用方法:
1. 获取Client对象

client = pymongo.MongoClient("localhost", 27017)
  1. 使用client获取database对象
db = client.test
  1. 如果需要可以使用database对象获取GridFS
fs = gridfs.GridFS(db, "images")
  1. 使用database对象存储document,python中可以直接存储字典数据
db.novel.save(dict(title=name, author=author, url=index, imag=_id, time=time.time()))db.novel.remove({"_id": _id})novels = bs_obj.findAll("div", {"class": "Sum Search_line"})
  1. 可以使用GridFS对文件进行存储、删除等操作
fs.put(rs.content,title=name, author=author, url=index)fs.delete(_img)fss = fs.find()
  1. 遍历查询结果,直接使用 for-in即可
for fl in fss:    print(fl.md5)
  1. 使用完毕后需要关闭资源
client.close()
  • request处理中文乱码问题:

request中貌似并没有直接处理字符集的工具,所以只能自己对相应体中的content进行编码判断,然后再decode。

rs = requests.get(url).content.decode("gbk")

到目前为止,我还没有发现比较有效的字符集判断方法,以前看过chardet,但是我认为那种判断方式效率过于底下,所以我还是使用的人工观测,然后直接指定字符集。

0 0