笔记整理——Python爬虫(四):数据持久化存储

笔记整理——Python爬虫(四):数据持久化存储

  • 数据持久化存储
    • 数据持久化存储 - csv文件
      • 作用
      • 使用流程
      • 示例1:创建 test.csv 文件,在文件中写入数据
      • 示例2:上一节的示例代码:猫眼电影,将爬取的数据存入本地 maoyan.csv 文件 - 使用writerow()方法实现
    • 数据持久化存储 - MySQL数据库
      • 示例3:将电影信息存入MySQL数据库(尽量使用executemany方法)
    • 数据持久化存储 - MongoDB数据库
      • 示例4:猫眼电影top100数据写入mongo
      • 示例5:电影天堂二级页面抓取
  • requests模块
    • 安装
    • requests.get()
    • 示例6:百度图片爬取

数据持久化存储

数据持久化存储 - csv文件

  • 作用

将爬取的数据存放到本地的csv文件中
  • 使用流程

1、导入模块
2、打开csv文件
3、初始化写入对象
4、写入数据(参数为列表)
import csv 

with open('film.csv','w') as f:
    writer = csv.writer(f)
    writer.writerow([])
  • 示例1:创建 test.csv 文件,在文件中写入数据

# 单行写入(writerow([]))
import csv
with open('test.csv','w',newline='') as f:
	writer = csv.writer(f)
	writer.writerow(['步惊云','36'])
	writer.writerow(['超哥哥','25'])

# 多行写入(writerows([(),(),()]
import csv
with open('test.csv','w',newline='') as f:
	writer = csv.writer(f)
	writer.writerows([('聂风','36'),('秦霜','25'),('孔慈','30')])
  • 示例2:上一节的示例代码:猫眼电影,将爬取的数据存入本地 maoyan.csv 文件 - 使用writerow()方法实现

import re
import csv
from urllib import request
from time import time,sleep
from random import randint
class MaoYanTop100Spider(object):
    '''
        面向对象编程

    '''
    def __init__(self):
        self.__url = 'https://maoyan.com/board/4?offset={}'
        # 计数变量
        self.__i = 0

    @property
    def url(self):
        return self.__url

    @property
    def i(self):
        return self.__i


    #私有实例方法:获取对应html内容
    def __get_html(self,url):
        headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
        req = request.Request(url=url,headers=headers)
        resp = request.urlopen(req)
        #返回获取的html内容
        html = resp.read().decode('utf-8')
        self.__parse_html(html)

    #私有实例方法:对获取的页面进行解析
    def __parse_html(self,html):
        re_bds = '
.*?title="(.*?)".*?class="star">(.*?)

.*?releasetime">(.*?)

' p = re.compile(re_bds, re.S) finall_list = p.findall(html) self.__save_html(finall_list) #私有实例方法:将解析得到的内容保存字典 def __save_html(self,finall_list): L = [] with open('maoyan.csv', 'a') as f: writer = csv.writer(f) for film in finall_list: t = ( film[0].strip(), film[1].strip(), film[2].strip()[5:15] ) L.append(t) writer.writerows(L) #公共接口 def display(self): print('程序开始执行,即将爬取top100榜单信息并写入csv文件,每10条将间隔三到五秒继续...') for i in range(0,91,10): url = self.__url.format(i) self.__get_html(url) sleep(randint(3,5)) print('数据写入结束!') print('爬取数量:%d' % self.__i) def test(): start = time() MaoYanTop100Spider().display() end = time() print('执行时间为:%.2f' % (end - start)) print('即将从本地csv文件中读取数据,请稍候...') with open('maoyan.csv','r') as f: reader = csv.reader(f) for row in reader: print(row) print('本地csv文件读取结束,程序结束!') if __name__ == '__main__': test() ======================================================================== 程序运行结果: anwc@anwc:~/文档/文档、代码杂七八$ python3 demo_spider_maoyan.py 程序开始执行,即将爬取top100榜单信息并写入csv文件,每10条将间隔三到五秒继续... 数据写入结束! 爬取数量:0 执行时间为:39.20 即将从本地csv文件中读取数据,请稍候... ['活着', '主演:葛优,巩俐,牛犇', '1994-05-17'] ['钢琴家', '主演:艾德里安·布洛迪,艾米莉娅·福克斯,米哈乌·热布罗夫斯基', '2002-05-24'] ['勇敢的心', '主演:梅尔·吉布森,苏菲·玛索,帕特里克·麦高汉', '1995-05-18'] ['阿飞正传', '主演:张国荣,张曼玉,刘德华', '2018-06-25'] ['射雕英雄传之东成西就', '主演:张国荣,梁朝伟,张学友', '1993-02-05'] ['爱·回家', '主演:俞承豪,金艺芬,童孝熙', '2002-04-05'] ['初恋这件小事', '主演:马里奥·毛瑞尔,平采娜·乐维瑟派布恩,阿查拉那·阿瑞亚卫考', '2012-06-05'] ['泰坦尼克号', '主演:莱昂纳多·迪卡普里奥,凯特·温丝莱特,比利·赞恩', '1998-04-03'] ['迁徙的鸟', '主演:雅克·贝汉,Philippe Labro', '2001-12-12'] ['蝙蝠侠:黑暗骑士', '主演:克里斯蒂安·贝尔,希斯·莱杰,阿伦·伊克哈特', '2008-07-14'] ['恐怖直播', '主演:河正宇,李璟荣,李大卫', '2013-07-31'] ['我爱你', '主演:宋在浩,李顺才,尹秀晶', '2011-02-17'] ['大闹天宫', '主演:邱岳峰,毕克,富润生', '1965-12-31'] ['剪刀手爱德华', '主演:约翰尼·德普,薇诺娜·瑞德,黛安娜·威斯特', '1990-12-06'] ['甜蜜蜜', '主演:黎明,张曼玉,杜可风', '2015-02-13'] ['闻香识女人', '主演:阿尔·帕西诺,克里斯·奥唐纳,加布里埃尔·安瓦尔', '1992-12-23'] ['英雄本色', '主演:狄龙,张国荣,周润发', '2017-11-17'] ['三傻大闹宝莱坞', '主演:阿米尔·汗,黄渤,卡琳娜·卡普', '2011-12-08'] ['黑客帝国3:矩阵革命', '主演:基努·里维斯,雨果·维文,凯瑞-安·莫斯', '2003-11-05'] ['触不可及', '主演:弗朗索瓦·克鲁塞,奥玛·希,安娜·勒尼', '2011-11-02'] ['忠犬八公物语', '主演:仲代达矢,春川真澄,井川比佐志', '1987-08-01'] ['辩护人', '主演:宋康昊,郭度沅,吴达洙', '2013-12-18'] ['喜剧之王', '主演:周星驰,莫文蔚,张柏芝', '1999-02-13'] ['黄金三镖客', '主演:克林特·伊斯特伍德,李·范·克里夫,埃里·瓦拉赫 Eli Wallach', '1966-12-23'] ['这个杀手不太冷', '主演:让·雷诺,加里·奥德曼,娜塔莉·波特曼', '1994-09-14'] ['借东西的小人阿莉埃蒂', '主演:志田未来,神木隆之介,大竹忍', '2010-07-17'] ['大话西游之月光宝盒', '主演:周星驰,莫文蔚,吴孟达', '2014-10-24'] ['一一', '主演:吴念真,金燕玲,李凯莉', '2000-05-15'] ['窃听风暴', '主演:乌尔里希·穆埃,塞巴斯蒂安·科赫,马蒂娜·格德克', '2006-03-23'] ['楚门的世界', '主演:金·凯瑞,劳拉·琳妮,诺亚·艾默里奇', '1998(罗马尼亚)'] ['飞屋环游记', '主演:爱德华·阿斯纳,乔丹·长井,鲍勃·彼德森', '2009-08-04'] ['哈尔的移动城堡', '主演:倍赏千惠子,木村拓哉,美轮明宏', '2004-09-05'] ['上帝之城', '主演:亚历桑德雷·罗德里格斯,艾莉丝·布拉加,莱安德鲁·菲尔米诺', '2002(俄罗斯)'] ['美丽心灵', '主演:罗素·克洛,詹妮弗·康纳利,艾德·哈里斯', '2001-12-13'] ['肖申克的救赎', '主演:蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿', '1994-09-10'] ['美丽人生', '主演:罗伯托·贝尼尼,尼可莱塔·布拉斯基,乔治·坎塔里尼', '2020-01-03'] ['倩女幽魂', '主演:张国荣,王祖贤,午马', '2011-04-30'] ['搏击俱乐部', '主演:爱德华·哈里森·诺顿,布拉德·皮特,海伦娜·伯翰·卡特', '1999-09-10'] ['春光乍泄', '主演:张国荣,梁朝伟,张震', '1997-05-17'] ['海上钢琴师', '主演:蒂姆·罗斯,比尔·努恩,克兰伦斯·威廉姆斯三世', '2019-11-15'] ['新龙门客栈', '主演:张曼玉,梁家辉,甄子丹', '2012-02-24'] ['驯龙高手', '主演:杰伊·巴鲁切尔,杰拉德·巴特勒,亚美莉卡·费雷拉', '2010-05-14'] ['教父2', '主演:阿尔·帕西诺,罗伯特·德尼罗,黛安·基顿', '1974-12-12'] ['美国往事', '主演:罗伯特·德尼罗,詹姆斯·伍兹,伊丽莎白·麦戈文', '2015-04-23'] ['魂断蓝桥', '主演:费雯·丽,罗伯特·泰勒,露塞尔·沃特森', '1940-05-17'] ['狮子王', '主演:马修·布罗德里克,尼基塔·卡兰姆,詹姆斯·厄尔·琼斯', '1995-07-15'] ['疯狂原始人', '主演:尼古拉斯·凯奇,艾玛·斯通,瑞安·雷诺兹', '2013-04-20'] ['唐伯虎点秋香', '主演:周星驰,巩俐,郑佩佩', '1993-07-01'] ['速度与激情5', '主演:范·迪塞尔,保罗·沃克,道恩·强森', '2011-05-12'] ['V字仇杀队', '主演:娜塔莉·波特曼,雨果·维文,斯蒂芬·瑞', '2005-12-11'] ['龙猫', '主演:秦岚,糸井重里,岛本须美', '2018-12-14'] ['本杰明·巴顿奇事', '主演:布拉德·皮特,凯特·布兰切特,塔拉吉·P·汉森', '2008-12-25'] ['指环王2:双塔奇兵', '主演:伊莱贾·伍德,伊恩·麦克莱恩,丽芙·泰勒', '2003-04-25'] ['指环王1:护戒使者', '主演:伊莱贾·伍德,伊恩·麦克莱恩,丽芙·泰勒', '2002-04-04'] ['时空恋旅人', '主演:瑞秋·麦克亚当斯,多姆纳尔·格里森,比尔·奈伊', '2013-09-04'] ['末代皇帝', '主演:尊龙,陈冲,彼得·奥图尔', '1987-10-23'] ['天空之城', '主演:寺田农,鹫尾真知子,龟山助清', '1992-05-01'] ['风之谷', '主演:岛本须美,永井一郎,坂本千夏', '1992-05'] ['幽灵公主', '主演:松田洋治,石田百合子,田中裕子', '1998-05-01'] ['蝙蝠侠:黑暗骑士崛起', '主演:克里斯蒂安·贝尔,迈克尔·凯恩,加里·奥德曼', '2012-08-27'] ['十二怒汉', '主演:亨利·方达,李·科布,马丁·鲍尔萨姆', '1957-04-13'] ['素媛', '主演:李来,薛耿求,严志媛', '2013-10-02'] ['大话西游之大圣娶亲', '主演:周星驰,朱茵,莫文蔚', '2014-10-24'] ['教父', '主演:马龙·白兰度,阿尔·帕西诺,詹姆斯·肯恩', '2015-04-18'] ['海洋', '主演:雅克·贝汉,姜文,兰斯洛特·佩林', '2011-08-12'] ['黑客帝国', '主演:基努·里维斯,凯瑞-安·莫斯,劳伦斯·菲什伯恩', '2000-01-14'] ['鬼子来了', '主演:姜文,姜宏波,陈强', '2000-05-13'] ['哈利·波特与死亡圣器(下)', '主演:丹尼尔·雷德克里夫,鲁伯特·格林特,艾玛·沃特森', '2011-08-04'] ['辛德勒的名单', '主演:连姆·尼森,拉尔夫·费因斯,本·金斯利', '1993-11-30'] ['指环王3:王者无敌', '主演:伊莱贾·伍德,伊恩·麦克莱恩,丽芙·泰勒', '2004-03-15'] ['7号房的礼物', '主演:柳承龙,郑镇荣,朴信惠', '2013-01-23'] ['盗梦空间', '主演:莱昂纳多·迪卡普里奥,渡边谦,约瑟夫·高登-莱维特', '2010-09-01'] ['加勒比海盗', '主演:约翰尼·德普,凯拉·奈特莉,奥兰多·布鲁姆', '2003-11-21'] ['当幸福来敲门', '主演:威尔·史密斯,贾登·史密斯,坦迪·牛顿', '2008-01-17'] ['穿条纹睡衣的男孩', '主演:阿沙·巴特菲尔德,维拉·法梅加,大卫·休里斯', '2008-08-28'] ['音乐之声', '主演:朱莉·安德鲁斯,克里斯托弗·普卢默,埃琳诺·帕克', '1965-03-02'] ['无间道', '主演:刘德华,梁朝伟,黄秋生', '2003-09-05'] ['致命魔术', '主演:休·杰克曼,克里斯蒂安·贝尔,迈克尔·凯恩', '2006-10-17'] ['小鞋子', '主演:默罕默德·阿米尔·纳吉,Kamal Mirkarimi,Behzad Rafi', '1997(伊朗)'] ['萤火之森', '主演:内山昂辉,佐仓绫音,后藤弘树', '2011-09-17'] ['少年派的奇幻漂流', '主演:苏拉·沙玛,伊尔凡·可汗,塔布', '2012-11-22'] ['断背山', '主演:希斯·莱杰,杰克·吉伦哈尔,米歇尔·威廉姆斯', '2005-09-02'] ['罗马假日', '主演:格利高里·派克,奥黛丽·赫本,埃迪·艾伯特', '1953-08-20'] ['夜访吸血鬼', '主演:汤姆·克鲁斯,布拉德·皮特,克尔斯滕·邓斯特', '1994-11-11'] ['天堂电影院', '主演:菲利浦·诺瓦雷,赛尔乔·卡斯特利托,蒂兹亚娜·罗达托', '1988-11-17'] ['怦然心动', '主演:玛德琳·卡罗尔,卡兰·麦克奥利菲,艾丹·奎因', '2010-07-26'] ['乱世佳人', '主演:费雯·丽,克拉克·盖博,奥利维娅·德哈维兰', '1939-12-15'] ['完美的世界', '主演:凯文·科斯特纳,克林特·伊斯特伍德,T·J·劳瑟', '1993-11-24'] ['霸王别姬', '主演:张国荣,张丰毅,巩俐', '1993-07-26'] ['七武士', '主演:三船敏郎,志村乔,千秋实', '1954-04-26'] ['忠犬八公的故事', '主演:Forest,理查·基尔,琼·艾伦', '2009-06-13'] ['海豚湾', '主演:里克·奥巴瑞,路易·西霍尤斯,哈迪·琼斯', '2009-07-31'] ['拯救大兵瑞恩', '主演:汤姆·汉克斯,马特·达蒙,汤姆·塞兹摩尔', '1998-11-13'] ['机器人总动员', '主演:本·贝尔特,艾丽莎·奈特,杰夫·格尔林', '2008-06-27'] ['神偷奶爸', '主演:史蒂夫·卡瑞尔,杰森·席格尔,拉塞尔·布兰德', '2010-06-20'] ['放牛班的春天', '主演:热拉尔·朱尼奥,让-巴蒂斯特·莫尼耶,玛丽·布奈尔', '2004-10-16'] ['熔炉', '主演:孔刘,郑有美,金智英', '2011-09-22'] ['阿凡达', '主演:萨姆·沃辛顿,佐伊·索尔达娜,米歇尔·罗德里格兹', '2010-01-04'] ['千与千寻', '主演:柊瑠美,周冬雨,入野自由', '2019-06-21'] ['无敌破坏王', '主演:约翰·C·赖利,萨拉·西尔弗曼,简·林奇', '2012-11-06'] 本地csv文件读取结束,程序结束!

数据持久化存储 - MySQL数据库

1、在数据库中建库建表

# 连接到mysql数据库
mysql -h127.0.0.1 -uroot -p123456
# 建库建表
create database maoyandb charset utf8;
use maoyandb;
create table filmtab(
name varchar(100),
star varchar(300),
time varchar(50)
)charset=utf8;
  • 2、回顾pymysql基本使用
一般方法:

import pymysql

# 创建2个对象
db = pymysql.connect('localhost','root','123456','maoyandb',charset='utf8')
cursor = db.cursor()

# 执行SQL命令并提交到数据库执行
# execute()方法第二个参数为列表传参补位
ins = 'insert into filmtab values(%s,%s,%s)'
cursor.execute(ins,['霸王别姬','张国荣','1993'])
db.commit()

# 关闭
cursor.close()
db.close()
  • 来试试高效的executemany()方法?
import pymysql

# 创建2个对象
db = pymysql.connect('192.168.153.137','tiger','123456','maoyandb',charset='utf8')
cursor = db.cursor()

# 抓取的数据
film_list = [('月光宝盒','周星驰','1994'),('大圣娶亲','周星驰','1994')]

# 执行SQL命令并提交到数据库执行
# execute()方法第二个参数为列表传参补位
cursor.executemany('insert into filmtab values(%s,%s,%s)',film_list)
db.commit()

# 关闭
cursor.close()
db.close()

示例3:将电影信息存入MySQL数据库(尽量使用executemany方法)

import re
import pymysql
from urllib import request
from time import time,sleep
from random import randint
class MaoYanTop100Spider(object):
    '''
        面向对象编程

    '''
    def __init__(self):
        self.__url = 'https://maoyan.com/board/4?offset={}'
        # 计数变量
        self.__i = 0
        self.db = pymysql.connect(
            'localhost', 'root', '123456', 'maoyandb',
            charset='utf8'
        )
        self.cursor = self.db.cursor()
    @property
    def url(self):
        return self.__url

    @property
    def i(self):
        return self.__i


    #私有实例方法:获取对应html内容
    def __get_html(self,url):
        headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
        req = request.Request(url=url,headers=headers)
        resp = request.urlopen(req)
        #返回获取的html内容
        html = resp.read().decode('utf-8')
        self.__parse_html(html)

    #私有实例方法:对获取的页面进行解析
    def __parse_html(self,html):
        re_bds = '
.*?title="(.*?)".*?class="star">(.*?)

.*?releasetime">(.*?)

' p = re.compile(re_bds, re.S) finall_list = p.findall(html) self.__save_html(finall_list) #私有实例方法:将解析得到的内容保存字典 def __save_html(self,finall_list): ins = 'insert into filmtab values(%s,%s,%s)' for film in finall_list: L = [ film[0], film[1].strip(), film[2].strip()[5:15] ] self.cursor.execute(ins, L) self.db.commit() #公共接口 def display(self): print('程序开始执行,即将爬取top100榜单信息并存入数据库,每10条将间隔三到五秒继续...') for i in range(0,91,10): url = self.__url.format(i) self.__get_html(url) sleep(randint(3,5)) print('数据写入结束!') print('爬取数量:%d' % self.__i) self.cursor.close() self.db.close() def test(): start = time() MaoYanTop100Spider().display() end = time() print('执行时间为:%.2f' % (end - start)) if __name__ == '__main__': test() executemany方法: from urllib import request import re import time import random from fake_useragent import UserAgent import pymysql class MaoyanSpider(object): def __init__(self): self.url = 'https://maoyan.com/board/4?offset={}' # 计数变量 self.i = 0 # 定义数据库连接 self.db = pymysql.connect( 'localhost', 'root', '123456', 'maoyandb', charset='utf8' ) self.cursor = self.db.cursor() # 定义列表,用来存放所有电影的元组 self.all_list = [] def get_html(self,url): headers = { 'User-Agent':UserAgent().random } req = request.Request(url=url,headers=headers) resp = request.urlopen(req) html = resp.read().decode('utf-8') # 直接调用解析函数 self.parse_html(html) def parse_html(self,html): re_bds = '
.*?title="(.*?)".*?class="star">(.*?)

.*?releasetime">(.*?)

' p = re.compile(re_bds,re.S) # film_list: [('','',''),()] film_list = p.findall(html) # 直接调用保存函数 self.save_html(film_list) def save_html(self,film_list): for film in film_list: self.all_list.append( (film[0],film[1].strip(),film[2][5:15]) ) def run(self): for offset in range(0,91,10): url = self.url.format(offset) self.get_html(url) # 休眠 time.sleep(random.uniform(0,1)) ins = 'insert into filmtab values(%s,%s,%s)' self.cursor.executemany(ins,self.all_list) self.db.commit() self.cursor.close() self.db.close() if __name__ == '__main__': start = time.time() spider = MaoyanSpider() spider.run() end = time.time() print('执行时间:%.2f' % (end-start))

数据持久化存储 - MongoDB数据库

  • pymongo操作mongodb数据库
import pymongo

# 1.数据库连接对象
conn=pymongo.MongoClient('localhost',27017)
# 2.库对象
db = conn['库名']
# 3.集合对象
myset = db['集合名']
# 4.插入数据
myset.insert_one({字典})
  • mongodb常用命令
mongo
>show dbs
>use 库名
>show collections
>db.集合名.find().pretty()
>db.集合名.count()
>db.dropDatabase()

示例4:猫眼电影top100数据写入mongo

from urllib import request
import re
import time
import random
from fake_useragent import UserAgent
import pymongo

class MaoyanSpider(object):
    def __init__(self):
        self.url = 'https://maoyan.com/board/4?offset={}'
        # 计数变量
        self.i = 0
        # 创建3个对象
        self.conn = pymongo.MongoClient(
            'localhost',27017
        )
        self.db = self.conn['maoyandb']
        self.myset = self.db['maoyanset']

    def get_html(self,url):
        # 使用随机User-Agent导致部分URL地址无法获取数据
        headers = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1' }
        req = request.Request(url=url,headers=headers)
        resp = request.urlopen(req)
        html = resp.read().decode('utf-8')
        # 直接调用解析函数
        self.parse_html(html)

    def parse_html(self,html):
        re_bds = '
.*?title="(.*?)".*?class="star">(.*?)

.*?releasetime">(.*?)

' p = re.compile(re_bds,re.S) # film_list: [('','',''),()] film_list = p.findall(html) # 直接调用保存函数 self.save_html(film_list) def save_html(self,film_list): for film in film_list: item = {} item['name'] = film[0].strip() item['star'] = film[1].strip() item['time'] = film[2].strip()[5:15] print(item) self.i += 1 # 把数据存入mongodb数据库 self.myset.insert_one(item) def run(self): for offset in range(0,31,10): url = self.url.format(offset) print(url) self.get_html(url) # 休眠 time.sleep(random.uniform(0,1)) print('数量:',self.i) if __name__ == '__main__': start = time.time() spider = MaoyanSpider() spider.run() end = time.time() print('执行时间:%.2f' % (end-start))

示例5:电影天堂二级页面抓取

需求:把电影天堂数据存入MySQL数据库 - 增量爬取
地址:电影天堂 - 2019年新片精品 - 更多
目标:电影名称、下载链接
分析:
*********一级页面需抓取***********
        1、电影详情页链接
        
*********二级页面需抓取***********
        1、电影名称
  			2、电影下载链接
实现步骤:
1、确定响应内容中是否存在所需抓取数据**
2、找URL规律**1页 :https://www.dytt8.net/html/gndy/dyzz/list_23_1.html
    第2页 :https://www.dytt8.net/html/gndy/dyzz/list_23_2.html
    ...
    第n页 :https://www.dytt8.net/html/gndy/dyzz/list_23_n.html
3、写正则表达式
	1、一级页面正则表达式
   		<table width="100%".*?<td width="5%".*?<a href="(.*?)".*?ulink">.*?</table>
	2、二级页面正则表达式
   		<div class="title_all"><h1><font color=#07519a>(.*?)
.*?======================================================================== 代码实现: 1.建库建表 create database filmskydb charset utf8; use filmskydb; create table request_finger( finger char(32) )charset=utf8; create table filmtab( name varchar(200), download varchar(500) )charset=utf8; 2.编码实现 from urllib import request import re import time import random from fake_useragent import UserAgent import pymysql from hashlib import md5 import sys class FilmSkySpider(object): def __init__(self): self.url = 'https://www.dytt8.net/html/gndy/dyzz/list_23_{}.html' self.db = pymysql.connect( 'localhost','root','123456','filmskydb', charset='utf8' ) self.cursor = self.db.cursor() # 功能函数1: 获取html函数 def get_html(self,url): headers = { 'User-Agent':UserAgent().random } req = request.Request(url=url,headers=headers) resp = request.urlopen(req) html = resp.read().decode('gb18030','ignore') return html # 功能函数2: 解析函数 def parse_func(self,re_bds,html): p = re.compile(re_bds,re.S) r_list = p.findall(html) return r_list # 解析提取所需数据 def parse_html(self,one_url): one_html = self.get_html(one_url) re_bds = '.*?
'
href_list = self.parse_func(re_bds,one_html) # href_list: ['/html/xxxx','/html/xxxx',''] for href in href_list: link = 'https://www.dytt8.net' + href s = md5() s.update(link.encode()) finger = s.hexdigest() ############################ if not self.is_go_on(finger): # 向详情页发请求,提取 名字和下载链接 self.parse_two_page(link) # 抓取1个电影之后,随机休眠 time.sleep(random.randint(1,2)) # 抓取完成后把finger存入到指纹表中 ins = 'insert into request_finger values(%s)' self.cursor.execute(ins,[finger]) self.db.commit() else: # 一旦抓取完成,直接退出进程 sys.exit('完成') # 判断finger在指纹表中是否存在 def is_go_on(self,finger): sel = 'select finger from request_finger where ' \ 'finger=%s' result = self.cursor.execute(sel,[finger]) if result: return True # 解析二级页面函数 def parse_two_page(self,link): two_html = self.get_html(link) re_bds = '

(.*?)

.*?=
self.parse_func(re_bds,two_html) # r_list: [('电影名称','下载链接')] item = {} if r_list: item['name'] = r_list[0][0].strip() item['download'] = r_list[0][1].strip() print(item) ins = 'insert into filmtab values(%s,%s)' L = [ item['name'],item['download'] ] self.cursor.execute(ins,L) self.db.commit() def run(self): for i in range(1,205): one_url = self.url.format(i) self.parse_html(one_url) if __name__ == '__main__': spider = FilmSkySpider() spider.run()

requests模块

安装

  • Linux
sudo pip3 install requests
  • Windows
# 方法一
   进入cmd命令行 :python -m pip install requests
# 方法二
   右键管理员进入cmd命令行 :pip install requests

requests.get()

  • 作用
# 向网站发起请求,并获取响应对象
res = requests.get(url,headers=headers)
  • 参数
1、url :需要抓取的URL地址
2、headers : 请求头
3、timeout : 超时时间,超过时间会抛出异常

  • 响应对象(res)属性
1、encoding :响应字符编码
   res.encoding = 'utf-8'
2、text :字符串
3、content :字节流
4、status_code :HTTP响应码
5、url :实际数据的URL地址

  • 非结构化数据保存
with open('xxx.jpg','wb') as f:
	f.write(res.content)

示例6:百度图片爬取

需求:保存任意想搜索的明星的图片到本地

编码实现:

import requests
from urllib import parse
import time
import random
import re
import os

class BaiduImage(object):
    def __init__(self):
        self.url = 'https://image.baidu.com/search/index?tn=baiduimage&word={}'
        self.headers = { 'User-Agent': 'Mozilla/5.0 '}

    def get_image(self,url,word):
        html = requests.get(url=url,headers=self.headers).text
        p = re.compile('"thumbURL":"(.*?)"',re.S)
        link_list = p.findall(html)
        print(link_list)
        # link_list: ['xxx.jpg','xxx.jpg']
        self.save_image(link_list,word)

    # 保存图片到指定路径
    def save_image(self,link_list,word):
        directory = '/home/tarena/images/{}/'.format(word)
        if not os.path.exists(directory):
            os.makedirs(directory)

        for link in link_list:
            html = requests.get(url=link,headers=self.headers).content
            filename = directory + link[-30:]
            with open(filename,'wb') as f:
                f.write(html)
            print(filename,'下载成功')

    def run(self):
        word = input('你想要谁的照片?请输入:')
        params = parse.quote(word)
        url = self.url.format(params)
        self.get_image(url,word)

if __name__ == '__main__':
    spider = BaiduImage()
    spider.run()

你可能感兴趣的:(教程)