14.python案例:爬取电影天堂中所有电视剧信息
1.python案例:爬取电影天堂中所有电视剧信息
1 #!/usr/bin/env python3 2 # -*- coding: UTF-8 -*- 3 '''================================================= 4 @Project -> File :pywork -> day10_test04 5 @IDE :PyCharm 6 @Author :xwl 7 @Date :2019/10/10 14:35 8 @Desc : 9 ==================================================''' 10 import requests,pyperclip,time,sys,os,pymysql 11 from lxml import etree 12 13 HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'} 14 URL = 'https://www.dytt8.net' # 电影天堂的主页(由于网站设置有问题,所以加了一个URL全局变量) 15 ALL_DATA=[] 16 17 # 清除剪切板中的内容 18 def clean_up(): 19 # 利用os模块中的popen方法调用电脑cmd.exe清除剪切板内容 20 # 用popen新建一个管道,然后用read()读取执行命令 21 result=os.popen('C:\Windows\System32\cmd.exe /c "echo off | clip"') 22 result.read() 23 24 # 倒计时程序 25 def countdown(num_time): 26 for i in range(num_time,-1,-1): 27 mystr = '倒计时' + str(i) + '秒开始!' 28 print(mystr, end='') 29 time.sleep(1) 30 print('\b' * len(mystr), end='') 31 print('倒计时结束!') 32 33 # 复制网址 34 def copy_url(): 35 clean_up() # 调用clean_up函数清除剪切板中内容 36 print('请从浏览器复制电影天堂网址!') 37 time.sleep(10) 38 print('*' * 50) 39 url = pyperclip.paste() # 将剪切板中的内容保存到变量中 40 if url == '': 41 print('未从浏览器获取到网址,请重新复制!') 42 time.sleep(1) 43 print('*' * 50) 44 num = 20 # 倒计时时间设定 45 print('请在{}内复制完成,否则程序将结束!'.format(num)) 46 time.sleep(1) 47 print('*' * 50) 48 countdown(num) # 调用countdown倒计时函数 49 url = pyperclip.paste() # 将剪切板中的内容保存到变量中 50 if url == '': # 如果仍旧未复制,则退出程序 51 sys.exit() 52 return url 53 54 # 解析网页工具 55 def parse_tool(url): 56 try: 57 response = requests.get(url, headers=HEADERS) 58 text = response.content.decode('gbk', errors='ignore') 59 except Exception as a: 60 print('网站无响应') 61 html = etree.HTML(text) 62 return html 63 64 # 获取需要爬取的网址 65 def get_url(): 66 url=copy_url() # 为了调试程序方便,临时将此处复制网址程序禁用掉 67 # url='https://www.dytt8.net/index.htm' # 正式运行程序时,此处代码需要禁用掉,而应该用上面的代码调用函数 68 return url 69 70 # 解析网页信息 71 def parse_url(): 72 73 # 解析电视剧网页信息 74 def parse_tvUrl(title,url): 75 print(title,url) # 输出结果:华语电视剧 https://www.dytt8.net/html/tv/hytv/ 76 print('-'*30) 77 # 提取华语电视剧网页共有几页的信息 78 html1=parse_tool(url) 79 option=html1.xpath('//div[@class="bd3r"]//div[@class="co_content8"]//select[@name="sldd"]/option[last()]/text()')[0] 80 for i in range(1,int(option)+1): 81 tv_list = [] # 将所有电视信息存入列表 82 # 遍历网页底部每页的网址 83 option_url='https://www.dytt8.net/html/tv/hytv/list_71_{}.html'.format(i) 84 html2=parse_tool(option_url) 85 href1s=html2.xpath('//div[@class="co_area2"]/div[@class="co_content8"]//table//td//a/@href') 86 # print('数量:',len(href1s)) # 调试用 87 print('第{}页'.format(i), '*' * 50) 88 for index,j in enumerate(href1s,1): # 用enumerate按顺序遍历,并带序号 89 tv_dict = {} # 将提取的电视名与下载地址保存在字典中 90 href1='https://www.dytt8.net'+j 91 html3=parse_tool(href1) 92 error=html3.xpath('//div[@align="center"]/div/text()') 93 if error!=[]: 94 print('网址有问题!') 95 continue 96 try: 97 tv_title=html3.xpath('//div[@class="co_area2"]/div[@class="title_all"]/h1/font[@color="#07519a"]/text()')[0] 98 # print(tv_title) # 调试用 99 tv_dict['tv_title']=tv_title 100 # 用contains进行模糊匹配 101 tv_download=html3.xpath('//div[@id="Zoom"]//table//td//a/@*') 102 # print(tv_download) # 调试用 103 tv_dict['tv_download']=tv_download 104 except Exception as a: 105 continue 106 tv_list.append(tv_dict) 107 # 添加数据爬取时的提示信息 108 str = '数据正在写入中' 109 for y in range(1,6): 110 print(str, end='') 111 str = '数据正在写入中'+'.'*y 112 time.sleep(0.1) 113 print('\b'*(len(str)),end='') 114 # print('计数',index) # 调试用 115 # print(tv_list) # 调试用 116 for index,info in enumerate(tv_list,1): 117 tv_title=info['tv_title'] 118 tv_download=info['tv_download'] 119 for k,j in enumerate(tv_download,1): 120 m = '第{}集'.format(k) 121 download=j 122 save_data(i,index,tv_title,m,download) 123 print('电视剧信息已写入数据库{}.'.format(i)) 124 125 # 解析电影网页信息 126 def parse_movieUrl(title,url): 127 print(title,url) # 输出结果:2019新片精品 https://www.dytt8.net/html/gndy/dyzz/index.html 128 print('-' * 30) 129 print('爬取电影信息代码未完成,等待后续开发。') 130 131 url=get_url() 132 html = parse_tool(url) 133 # response=requests.get(url,headers=HEADERS) 134 # text=response.content.decode('gbk',errors='ignore') 135 # html=etree.HTML(text) 136 # 因为源代码中按下面的路径查找divs1列表中有两个元素,而我们只是需要爬取第一个元素中 137 # 的内容,所以用list[0],然后在对该元素进行xpath查找 138 divs1=html.xpath('//div[@class="bd3r"]//div[@class="bd3rl"]')[0] 139 divs=divs1.xpath('./div[@class="co_area2"]') 140 tv_url={} 141 movie_url={} 142 for div in divs: 143 # -------------提取电视剧分类--------------# 144 # 将列表中的每一个元素提取出来,存入变量title 145 main_title = div.xpath('./div[@class="title_all"]/p/strong/text()')[0] 146 main_url=div.xpath('./div[@class="title_all"]/p/em/a/@href')[0] 147 # 由于电影天堂网站有个问题,即日韩电视剧后面跟的是完整的网址,而其 148 # 它的不是,所以需要进行一个判断操作 149 if main_title=='华语电视剧': 150 tv_url['main_title'] = main_title 151 tv_url['main_url']=URL + main_url 152 # -------------提取电影网址--------------# 153 elif main_title=='2019新片精品': 154 movie_url['movie_title']=main_title 155 movie_url['main_url'] = URL + main_url 156 else: 157 continue 158 # 调用电视剧解析函数解析网页信息 159 parse_tvUrl(tv_url['main_title'],tv_url['main_url']) 160 # 调用电影解析函数解析网页信息 161 parse_movieUrl(movie_url['movie_title'],movie_url['main_url']) 162 163 # 数据写入数据库 164 def save_data(i,n,data1,m,data2): 165 table_name = 'xwl_{}'.format(i) # 变量类型的数据库表名 166 conn=pymysql.connect(host='localhost',user='root', 167 password='root',charset='utf8',port=3306) 168 cursor=conn.cursor() 169 try: 170 # 创建一个名为xwl_test的数据库 171 cursor.execute('create database if not exists xwl_test character set utf8;') 172 cursor.execute('use xwl_test;') 173 # 创建一个变量类型的数据库表名 174 sql1="create table if not exists `%s`(序号 int,电视剧名称 char(255),集数 char(20),下载地址 char(255)) character set utf8" %(table_name) 175 cursor.execute(sql1) 176 # 向变量类型的数据库表名中写入数据 177 sql2="insert into `%s`(序号,电视剧名称,集数,下载地址)" %(table_name) +" values(%s,%s,%s,%s)" 178 cursor.execute(sql2,(n,data1,m,data2)) 179 conn.commit() 180 except Exception as e: 181 print('有部分数据写入出错') # 这样就可以在数据写入出错时自动跳过,从而使代码可以继续跑下去 182 finally: 183 conn.close() 184 185 #--------------代码调用主模块---------------# 186 if __name__=='__main__': 187 parse_url()
出现以下情况,说明已经成功写入: