大师兄的Python学习笔记(二十二): 爬虫(三)

师兄的Python学习笔记(二十一): 爬虫(二)
大师兄的Python学习笔记(二十三): 爬虫(四)

四、保存数据

  • 数据在提取后,即可以保存在文件中,也可以保存在数据库中。
4.1 文件存储
4.1.1 存储到txt文件
  • 存储到txt文件是最基础的数据保存方式。
>>>from pyquery import PyQuery as pq
>>>import requests

>>>def sort_data(func):
>>>    def deco(*args,**kargs):
>>>        # 处理内容
>>>        data = func(*args,**kargs)
>>>        html_data = pq(data)
>>>        hd = html_data('.hd')
>>>        bd = html_data('.bd')

>>>        index = [x.text() for x in html_data.find('em').items()]
>>>        name = [x.text() for x in hd.find('.title:first-child').items()]
>>>        director_actor = [x.html().strip().split('
')[0] for x in bd.children('.star').siblings('p:first-of-type').items()] >>> director = [x.split('\xa0\xa0\xa0')[0] for x in director_actor] >>> actor = [x.split('\xa0\xa0\xa0')[1] for x in director_actor] >>> star = bd('.star')('span:nth-child(4)').text().split() >>> link = [x.attr.href for x in hd('a').items()] >>> result = zip(index,name,director,actor,star,link) >>> return result >>> return deco >>>@sort_data >>>def get_page(url): >>> # 获得页面内容 >>> headers = { >>> 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like >>>>Gecko) Chrome/78.0.3904.108 Safari/537.36' >>> } >>> res = requests.get(url=url,headers=headers) >>> if res.status_code == 200: >>> return res.text # 获得HTML页面 >>> else: >>> return None >>>def save_to_txt(data,filename="douban_top10.txt"): >>> # 保存到txt文档 >>> with open(filename,'w',encoding='utf-8') as file: >>> for i in range(10): >>> line = f'{" ".join(list(next(data)))}\n' >>> file.write(line) >>>def main(): >>> # 入口 >>> url = 'https://movie.douban.com/top250' >>> page_data = get_page(url) >>> save_to_txt(page_data) >>>if __name__ == '__main__': >>> main()
4.1.2 存储为json文件
  • 大师兄的Python学习笔记(十九): Python与(XML和JSON)
  • json格式非常方便前端使用。
>>>from pyquery import PyQuery as pq
>>>import requests,json

>>>def sort_data(func):
>>>    def deco(*args,**kargs):
>>>        # 处理内容
>>>        data = func(*args,**kargs)
>>>        html_data = pq(data)
>>>        hd = html_data('.hd')
>>>        bd = html_data('.bd')

>>>        index = [x.text() for x in html_data.find('em').items()]
>>>        name = [x.text() for x in hd.find('.title:first-child').items()]
>>>        director_actor = [x.html().strip().split('
')[0] for x in bd.children('.star').siblings('p:first-of-type').items()] >>> director = [x.split('\xa0\xa0\xa0')[0] for x in director_actor] >>> actor = [x.split('\xa0\xa0\xa0')[1] for x in director_actor] >>> star = bd('.star')('span:nth-child(4)').text().split() >>> link = [x.attr.href for x in hd('a').items()] >>> result = zip(index,name,director,actor,star,link) >>> return result >>> return deco >>>@sort_data >>>def get_page(url): >>> # 获得页面内容 >>> headers = { >>> 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like >>>>Gecko) Chrome/78.0.3904.108 Safari/537.36' >>> } >>> res = requests.get(url=url,headers=headers) >>> if res.status_code == 200: >>> return res.text # 获得HTML页面 >>> else: >>> return None >>>def save_to_json(data,filename="douban_top10.json"): >>> # 保存到json文档 >>> with open(filename,'w',encoding='utf-8') as file: >>> for i in range(10): >>> json.dump(next(data),file) >>>def main(): >>> # 入口 >>> url = 'https://movie.douban.com/top250' >>> page_data = get_page(url) >>> save_to_json(page_data) >>>if __name__ == '__main__': >>> main()
4.1.3 存储为pickle文件
  • pickle支持直接保存Python的大部分数据类型,但只能在Python中使用。
>>>from pyquery import PyQuery as pq
>>>import requests,pickle

>>>def sort_data(func):
>>>    def deco(*args,**kargs):
>>>        # 处理内容
>>>        data = func(*args,**kargs)
>>>        html_data = pq(data)
>>>        hd = html_data('.hd')
>>>        bd = html_data('.bd')

>>>        index = [x.text() for x in html_data.find('em').items()]
>>>        name = [x.text() for x in hd.find('.title:first-child').items()]
>>>        director_actor = [x.html().strip().split('
')[0] for x in bd.children('.star').siblings('p:first-of-type').items()] >>> director = [x.split('\xa0\xa0\xa0')[0] for x in director_actor] >>> actor = [x.split('\xa0\xa0\xa0')[1] for x in director_actor] >>> star = bd('.star')('span:nth-child(4)').text().split() >>> link = [x.attr.href for x in hd('a').items()] >>> result = zip(index,name,director,actor,star,link) >>> return result >>> return deco >>>@sort_data >>>def get_page(url): >>> # 获得页面内容 >>> headers = { >>> 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like >>>>Gecko) Chrome/78.0.3904.108 Safari/537.36' >>> } >>> res = requests.get(url=url,headers=headers) >>> if res.status_code == 200: >>> return res.text # 获得HTML页面 >>> else: >>> return None >>>def save_to_pickle(data,filename="douban_top10.pk"): >>> # 保存到pickle文档 >>> with open(filename,'wb') as file: >>> pickle.dump(data,file) >>>def main(): >>> # 入口 >>> url = 'https://movie.douban.com/top250' >>> page_data = get_page(url) >>> save_to_pickle(page_data) >>>if __name__ == '__main__': >>> main()
4.1.4 存储为shelve文件
  • shelve支持所有的Python数据类型,但只能在Python中使用。
  • 可以把shelve看成是一个临时的缓存数据库。
  • 操作方法类似字典。
>>>from pyquery import PyQuery as pq
>>>import requests,shelve

>>>def sort_data(func):
>>>    def deco(*args,**kargs):
>>>        # 处理内容
>>>        data = func(*args,**kargs)
>>>        html_data = pq(data)
>>>        hd = html_data('.hd')
>>>        bd = html_data('.bd')

>>>        index = [x.text() for x in html_data.find('em').items()]
>>>        name = [x.text() for x in hd.find('.title:first-child').items()]
>>>        director_actor = [x.html().strip().split('
')[0] for x in bd.children('.star').siblings('p:first-of-type').items()] >>> director = [x.split('\xa0\xa0\xa0')[0] for x in director_actor] >>> actor = [x.split('\xa0\xa0\xa0')[1] for x in director_actor] >>> star = bd('.star')('span:nth-child(4)').text().split() >>> link = [x.attr.href for x in hd('a').items()] >>> result = zip(index,name,director,actor,star,link) >>> return result >>> return deco >>>@sort_data >>>def get_page(url): >>> # 获得页面内容 >>> headers = { >>> 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like >>>>Gecko) Chrome/78.0.3904.108 Safari/537.36' >>> } >>> res = requests.get(url=url,headers=headers) >>> if res.status_code == 200: >>> return res.text # 获得HTML页面 >>> else: >>> return None >>>def save_to_shelve(data,filename="douban_top10.db"): >>> # 保存到pickle文档 >>> with shelve.open(filename) as db: >>> for i in range(10): >>> db[f"{i+1}"] = next(data) >>>def main(): >>> # 入口 >>> url = 'https://movie.douban.com/top250' >>> page_data = get_page(url) >>> save_to_shelve(page_data) >>>if __name__ == '__main__': >>> main()
4.1.5 存储为csv文件
  • csv文件可以看作是纯文本格式的xls文件。
>>>from pyquery import PyQuery as pq
>>>import requests,csv

>>>def sort_data(func):
>>>    def deco(*args,**kargs):
>>>        # 处理内容
>>>        data = func(*args,**kargs)
>>>        html_data = pq(data)
>>>        hd = html_data('.hd')
>>>        bd = html_data('.bd')

>>>        index = [x.text() for x in html_data.find('em').items()]
>>>        name = [x.text() for x in hd.find('.title:first-child').items()]
>>>        director_actor = [x.html().strip().split('
')[0] for x in bd.children('.star').siblings('p:first-of-type').items()] >>> director = [x.split('\xa0\xa0\xa0')[0] for x in director_actor] >>> actor = [x.split('\xa0\xa0\xa0')[1] for x in director_actor] >>> star = bd('.star')('span:nth-child(4)').text().split() >>> link = [x.attr.href for x in hd('a').items()] >>> result = zip(index,name,director,actor,star,link) >>> return result >>> return deco >>>@sort_data >>>def get_page(url): >>> # 获得页面内容 >>> headers = { >>> 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like >>>>Gecko) Chrome/78.0.3904.108 Safari/537.36' >>> } >>> res = requests.get(url=url,headers=headers) >>> if res.status_code == 200: >>> return res.text # 获得HTML页面 >>> else: >>> return None >>>def save_to_csv(data,filename="douban_top10.csv"): >>> # 保存到pickle文档 >>> with open(filename,'w',encoding='utf-8') as file: >>> writer = csv.writer(file) >>> writer.writerows(data) >>>def main(): >>> # 入口 >>> url = 'https://movie.douban.com/top250' >>> page_data = get_page(url) >>> save_to_csv(page_data) >>>if __name__ == '__main__': >>> main()
4.2 数据库存储
4.2.1 存储到MySQL
  • MySQL是目前最流行的关系型数据库之一。
  • 通过行和列组成的二维表存储。
  • 以本地MySQL server为例。
>>>from pyquery import PyQuery as pq
>>>import pymysql
>>>import requests

>>>def sort_data(func):
>>>    def deco(*args,**kargs):
>>>        # 处理内容
>>>        data = func(*args,**kargs)
>>>        html_data = pq(data)
>>>        hd = html_data('.hd')
>>>        bd = html_data('.bd')

>>>        index = [x.text() for x in html_data.find('em').items()]
>>>        name = [x.text() for x in hd.find('.title:first-child').items()]
>>>        director_actor = [x.html().strip().split('
')[0] for x in bd.children('.star').siblings('p:first-of-type').items()] >>> director = [x.split('\xa0\xa0\xa0')[0] for x in director_actor] >>> actor = [x.split('\xa0\xa0\xa0')[1] for x in director_actor] >>> star = bd('.star')('span:nth-child(4)').text().split() >>> link = [x.attr.href for x in hd('a').items()] >>> result = zip(index,name,director,actor,star,link) >>> return result >>> return deco >>>@sort_data >>>def get_page(url): >>> # 获得页面内容 >>> headers = { >>> 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like >>>>Gecko) Chrome/78.0.3904.108 Safari/537.36' >>> } >>> res = requests.get(url=url,headers=headers) >>> if res.status_code == 200: >>> return res.text # 获得HTML页面 >>> else: >>> return None >>>def save_to_mysql_db(data,host='localhost',user='root',password='root',port=3306,db='note_sample',table='douban_top10'): >>> # 连接到mysql服务器 >>> db = pymysql.connect(host=host,user=user,password=password,port=port,db=db,charset='utf8') >>> with db: >>> cursor = db.cursor() >>> # 如果没有表就创建表 >>> sql_create_table = f'CREATE TABLE IF NOT EXISTS {str(table)}(ind_order VARCHAR(255) NOT NULL PRIMARY KEY, name VARCHAR(255) NOT NULL, director VARCHAR(255), actor VARCHAR(255), star VARCHAR(255), link_to VARCHAR(255))' >>> cursor.execute(sql_create_table) >>> db.commit() >>> for i in range(10): >>> next_data = next(data) >>> sql_insert_data = f'INSERT INTO {table}(ind_order,name,director,actor,star,link_to) VALUES({next_data[0]}, "{next_data[1]}", "{next_data[2]}", "{next_data[3]}", "{next_data[4]}", "{next_data[5]}")' >>> try: >>> cursor.execute(sql_insert_data) >>> except Exception as e: >>> print(e) >>> db.rollback() >>> db.commit() >>>def main(): >>> # 入口 >>> url = 'https://movie.douban.com/top250' >>> page_data = get_page(url) >>> save_to_mysql_db(page_data) >>>if __name__ == '__main__': >>> main()
4.2.2 存储到MongoDB
  • MongoDB是基于分布式文件存储的开源非关系型数据库。
  • 内容存储类似JSON格式。
  • 以单机版MongoDB为例。
>>>from pyquery import PyQuery as pq
>>>import pymongo
>>>import requests

>>>def sort_data(func):
>>>    def deco(*args,**kargs):
>>>        # 处理内容
>>>        data = func(*args,**kargs)
>>>        html_data = pq(data)
>>>        hd = html_data('.hd')
>>>        bd = html_data('.bd')

>>>        index = [x.text() for x in html_data.find('em').items()]
>>>        name = [x.text() for x in hd.find('.title:first-child').items()]
>>>        director_actor = [x.html().strip().split('
')[0] for x in bd.children('.star').siblings('p:first-of-type').items()] >>> director = [x.split('\xa0\xa0\xa0')[0] for x in director_actor] >>> actor = [x.split('\xa0\xa0\xa0')[1] for x in director_actor] >>> star = bd('.star')('span:nth-child(4)').text().split() >>> link = [x.attr.href for x in hd('a').items()] >>> result = zip(index,name,director,actor,star,link) >>> return result >>> return deco >>>@sort_data >>>def get_page(url): >>> # 获得页面内容 >>> headers = { >>> 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like >>>>Gecko) Chrome/78.0.3904.108 Safari/537.36' >>> } >>> res = requests.get(url=url,headers=headers) >>> if res.status_code == 200: >>> return res.text # 获得HTML页面 >>> else: >>> return None >>>def save_to_mongo_db(data,host='localhost',port=27017,db='note_sample',collection='douban_top10'): >>> # 连接到mongodb >>> client = pymongo.MongoClient(host=host, port=port) >>> db = client[db] # 创建数据库 >>> collection = db[collection] # 获得集合 >>> for i in range(10): >>> next_data = dict((title,value) for title,value in zip(['ind','name','director','actor','stars','link'],next(data))) >>> collection.insert_one(next_data) >>>def main(): >>> # 入口 >>> url = 'https://movie.douban.com/top250' >>> page_data = get_page(url) >>> save_to_mongo_db(page_data) >>>if __name__ == '__main__': >>> main()
4.2.3 存储到Redis
  • Redis是一款基于内存非关系型数据库。
  • 基于键值对保存。
>>>from pyquery import PyQuery as pq
>>>from redis import StrictRedis
>>>import requests

>>>def sort_data(func):
>>>    def deco(*args,**kargs):
>>>        # 处理内容
>>>        data = func(*args,**kargs)
>>>        html_data = pq(data)
>>>        hd = html_data('.hd')
>>>        bd = html_data('.bd')

>>>        index = [x.text() for x in html_data.find('em').items()]
>>>        name = [x.text() for x in hd.find('.title:first-child').items()]
>>>        director_actor = [x.html().strip().split('
')[0] for x in bd.children('.star').siblings('p:first-of-type').items()] >>> director = [x.split('\xa0\xa0\xa0')[0] for x in director_actor] >>> actor = [x.split('\xa0\xa0\xa0')[1] for x in director_actor] >>> star = bd('.star')('span:nth-child(4)').text().split() >>> link = [x.attr.href for x in hd('a').items()] >>> result = zip(index,name,director,actor,star,link) >>> return result >>> return deco >>>@sort_data >>>def get_page(url): >>> # 获得页面内容 >>> headers = { >>> 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like >>>>Gecko) Chrome/78.0.3904.108 Safari/537.36' >>> } >>> res = requests.get(url=url,headers=headers) >>> if res.status_code == 200: >>> return res.text # 获得HTML页面 >>> else: >>> return None >>>def save_to_redis(data,host='localhost',port=6379,db=0,password=None): >>> # 连接到redis >>> redis = StrictRedis(host=host,port=port,db=db,password=password) >>> for i in range(10): >>> next_data = next(data) >>> redis.set(next_data[0]," ".join(next_data[1:])) >>>def main(): >>> # 入口 >>> url = 'https://movie.douban.com/top250' >>> page_data = get_page(url) >>> save_to_redis(page_data) >>>if __name__ == '__main__': >>> main()

参考资料


  • https://blog.csdn.net/u010138758/article/details/80152151 J-Ombudsman
  • https://www.cnblogs.com/zhuluqing/p/8832205.html moisiet
  • https://www.runoob.com 菜鸟教程
  • http://www.tulingxueyuan.com/ 北京图灵学院
  • http://www.imooc.com/article/19184?block_id=tuijian_wz#child_5_1 两点水
  • https://blog.csdn.net/weixin_44213550/article/details/91346411 python老菜鸟
  • https://realpython.com/python-string-formatting/ Dan Bader
  • https://www.liaoxuefeng.com/ 廖雪峰
  • https://blog.csdn.net/Gnewocean/article/details/85319590 新海说
  • https://www.cnblogs.com/Nicholas0707/p/9021672.html Nicholas
  • https://www.cnblogs.com/dalaoban/p/9331113.html 超天大圣
  • https://blog.csdn.net/zhubao124/article/details/81662775 zhubao124
  • https://blog.csdn.net/z59d8m6e40/article/details/72871485 z59d8m6e40
  • 《Python学习手册》Mark Lutz
  • 《Python编程 从入门到实践》Eric Matthes
  • 《Python3网络爬虫开发实战》崔庆才

本文作者:大师兄(superkmi)

你可能感兴趣的:(大师兄的Python学习笔记(二十二): 爬虫(三))