前面讲了如何通过pymysql操作数据库,这次写一个爬虫来提取信息,并将数据存储到mysql数据库
1.爬取目标
爬取猫眼电影TOP100榜单
要提取的信息包括:电影排名、电影名称、上映时间、分数
2.分析网页HTML源码
可以看到每部电影信息都被包裹在一对<dd>...</dd>标签中,所以我们只需提取出一个标签对中的上述信息即可。使用正则表达式提取
3. 完整过程
这个例子有2个关键点:正则编写和数据处理(写进mysql数据库)
(1) 正则表达式的编写
pattern = re.compile(r‘<dd>.*?<i.*?>(\d+)</i>.*?‘ # 匹配电影排名 r‘<p class="name"><a.*?data-val=".*?">(.*?)‘ # 匹配电影名称 r‘</a>.*?<p.*?class="releasetime">(.*?)</p>‘ # 匹配上映时间 r‘.*?<i.*?"integer">(.*?)</i>‘ # 匹配分数的整数位 r‘.*?<i.*?"fraction">(.*?)</i>.*?</dd>‘,re.S) # 匹配分数小数位,re.S表示跨行匹配 m = pattern.findall(html) # print(m)
使用findall()方法来匹配所有符合规则的字符,返回一个列表,下面是其中一页的匹配结果
(2)完整代码,注意get_data()函数时如何处理数据,然后通过write_sql()函数是写入数据库的
# coding: utf-8 # author: hmk import requests import re import pymysql def get_html(url,header): response = requests.get(url,headers=header) if response.status_code == 200: return response.text else: return None def get_data(html,list_data): pattern = re.compile(r‘<dd>.*?<i.*?>(\d+)</i>.*?‘ # 匹配电影排名 r‘<p class="name"><a.*?data-val=".*?">(.*?)‘ # 匹配电影名称 r‘</a>.*?<p.*?class="releasetime">(.*?)</p>‘ # 匹配上映时间 r‘.*?<i.*?"integer">(.*?)</i>‘ # 匹配分数的整数位 r‘.*?<i.*?"fraction">(.*?)</i>.*?</dd>‘,re.S) # 匹配分数小数位 m = pattern.findall(html) for i in m: # 因为匹配到的所有结果会以列表形式返回,每部电影信息以元组形式保存,所以可以迭代处理每组电影信息 ranking = i[0] # 提取一组电影信息中的排名 movie = i[1] # 提取一组电影信息中的名称 release_time = i[2] # 提取一组电影信息中的上映时间 score = i[3] + i[4] # 提取一组电影信息中的分数,这里把分数的整数部分和小数部分拼在一起 list_data.append([ranking,movie,release_time,score]) # 每提取一组电影信息就放到一个列表中,同时追加到一个大列表里,这样最后得到的大列表就包含所有电影信息 def write_sql(data): conn = pymysql.connect(host=‘localhost‘,user=‘root‘,password=‘123456‘,db=‘test‘,charset=‘utf8‘) cur = conn.cursor() for i in data: """这里的data参数是指正则匹配并处理后的列表数据(是一个大列表,包含所有电影信息,每个电影信息都存在各自的一个列表中; 对大列表进行迭代,提取每组电影信息,这样提取到的每组电影信息都是一个小列表,然后就可以把每组电影信息写入数据库了)""" movie = i # 每组电影信息,这里可以看做是准备插入数据库的每组电影数据 sql = "insert into maoyan_movie(ranking,score) values(%s,%s,%s)" # sql插入语句 try: cur.execute(sql,movie) # 执行sql语句,movie即是指要插入数据库的数据 conn.commit() # 插入完成后,不要忘记提交操作 print(‘导入成功‘) except: print(‘导入失败‘) cur.close() # 关闭游标 conn.close() # 关闭连接 def main(): start_url = ‘http://maoyan.com/board/4‘ depth = 10 # 爬取深度(翻页) header = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Accept-Encoding": "gzip,deflate,sdch","Accept-Language": "zh-CN,zh;q=0.8","Cache-Control": "max-age=0","Connection": "keep-alive","Host": "maoyan.com","Referer": "http://maoyan.com/board","Upgrade-Insecure-Requests": "1","User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/49.0.2623.75 Safari/537.36"} for i in range(depth): url = start_url + ‘?offset=‘ + str(10 * i) html = get_html(url,header) list_data = [] get_data(html,list_data) write_sql(list_data) #print(list_data) # for i in list_data: # t = i # print(t) if __name__ == "__main__": main()
注意一点,在请求url时,加了headers,这里必须加,估计是网站做了限制,直接爬的话会失败,可能认出请求链接的不是一个人而是一只虫了~~~
代码中注释写得很详细,不再过多描述了
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。