exam2
发布时间 : 2023-12-11 09:31
字数:3.5k
阅读 :
网络爬虫 (一)显示影片基本信息 访问豆瓣电影Top250(https://movie.douban.com/top250?start=0),获取每部电影的中文片名、排名、评分及其对应的链接,按照“排名-中文片名-评分-链接”的格式显示在屏幕上。
参考步骤及代码:
1) 在PyCharm中新建工程包,命名为webCrawler; 2) 在webCrawler工程下新建doubanCrawler文件夹; 3) 在doubanCrawler文件夹下创建getTop250.py文件; 4) 获取豆瓣Top250基本信息代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ? import requests ? from bs4 import BeautifulSoup ? import time ? ? def page_request (url, ua) : ? response = requests.get(url=url, headers=ua) ? html = response.content.decode('utf-8' ) ? return html ? ? def page_parse (html) : ? soup = BeautifulSoup(html, 'lxml' ) ? ? position = soup.select('#content > div > div.article > ol > li > div > div.pic > em' ) ? ? name = soup.select('#content > div > div.article > ol > li > div > div.info > div.hd > a > span:nth-child(1)' ) ? ? rating = soup.select('#content > div > div.article > ol > li> div > div.info > div.bd > div > span.rating_num' ) ? ? href = soup.select('#content > div > div.article > ol > li > div > div.info > div.hd > a' ) ? for i in range(len(name)): ? print(position[i].get_text()+'\t' +name[i].get_text()+'\t' + rating[i].get_text() + '\t' + href[i].get('href' )) ? ? if __name__ == "__main__" : ? print('**************开始爬取豆瓣电影**************' ) ? ua = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4421.5 Safari/537.36' } ? ? for startNum in range(0 , 251 , 25 ): ? url = "https://movie.douban.com/top250?start=%d" % startNum ? html = page_request(url=url, ua=ua) ? page_parse(html=html) ? print('**************爬取完成**************' )
(二)存储影片详细信息 访问豆瓣电影Top250(https://movie.douban.com/top250?start=0),在问题1的基础上,获取每部电影的导演、编剧、主演、类型、上映时间、片长、评分人数以及剧情简介等信息,并将获取到的信息保存至本地文件中。
参考步骤及过程:
1) 在实验1创建的工程包webCrawler下的doubanCrawler文件夹下创建downloadTop250.py; 2) 参考代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 ? import requests ? from bs4 import BeautifulSoup ? import re ? import docx ? from docx.oxml.ns import qn ? ? ? def page_request (url, ua) : ? response = requests.get(url=url, headers=ua) ? html = response.content.decode('utf-8' ) ? return html ? ? ? def page_parse (html, ua) : ? soup = BeautifulSoup(html, 'lxml' ) ? for tag in soup.find_all(attrs={'class' : 'item' }): ? data = [] ? ? num = tag.find('em' ).get_text() ? data.append(num) ? ? name = tag.find_all(attrs={'class' : 'title' })[0 ].get_text() ? data.append(name) ? ? href = tag.find(attrs={'class' : 'hd' }).a ? url = href.attrs['href' ] ? data.append('豆瓣链接:' + url) ? ? info = tag.find(attrs={'class' : 'star' }).get_text() ? info = info.replace('\n' , '' ).lstrip() ? ? mode = re.compile(r'\d+\.?\d' ) ? i = 0 ? for n in mode.findall(info): ? if i == 0 : ? ? data.append('豆瓣评分:' + n) ? elif i == 1 : ? ? data.append('评分人数:' + n) ? i = i + 1 ? ? sub_page_requests(url, ua, data) ? print('第%s部电影信息爬取完成' % num) ? ? ? ? def sub_page_requests (url, ua, data) : ? html = page_request(url=url, ua=ua) ? soup = BeautifulSoup(html, 'lxml' ) ? ? info = soup.find(attrs={'id' : 'info' }).get_text() ? data.append(info) ? ? summary = soup.find(attrs={'property' : 'v:summary' }).get_text() ? summary = summary.replace('\n' , '' ).replace(' ' , '' ).lstrip() ? data.append(data[1 ] + '影片简介:\n' + summary) ? ? save(data) ? ? def save (data) : ? file = docx.Document() ? ? file.styles['Normal' ].font.name = u'Times New Roman' ? file.styles['Normal' ].element.rPr.rFonts.set(qn('w:eastAsia' ), u'Times New Roman' ) ? ? ? for element in data: ? file.add_paragraph(element) ? file.save('result/' + data[0 ] + '、' + data[1 ] + '.docx' ) ? ? if __name__ == "__main__" : ? print('**************开始爬取豆瓣电影**************' ) ? ua = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4421.5 Safari/537.36' } ? ? data_List = [] ? for startNum in range(0 , 251 , 25 ): ? url = "https://movie.douban.com/top250?start=%d" % startNum ? html = page_request(url=url, ua=ua) ? ? page_parse(html=html, ua=ua) ? print('**************爬取完成**************' )
熟悉Flume的基本使用方法 2.Kafka链接Flume 编写Flume配置文件,将Kafka作为输入,通过Flume将Kafka生产者输入的信息存入HDFS中,存储格式hdfs://localhost:9000/fromkafka/%Y%m%d/,要求存储时文件名为kafka_log。(注:配置好Flume后生产者输入的信息不会实时写入到HDFS,一段时间后批量写入)
【参考答案】 Flume配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 ? #文件名Ekafka2hdfs.conf ? #设置名称 ? a1.sources=r1 ? a1.sinks=k1 ? a1.channels=c1 ? ? #配置Source ? a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource ? a1.sources.r1.batchSize = 500 ? a1.sources.r1.batchDurationMillis = 2000 ? a1.sources.r1.kafka.bootstrap.servers = localhost:9092 ? a1.sources.r1.kafka.topics = flume ? ? #配置Sink ? a1.sinks.k1.type = hdfs ? a1.sinks.k1.hdfs.path = hdfs://localhost:9000/fromkafka/%Y%m%d/ ? a1.sinks.k1.hdfs.filePrefix = kafka_log ? a1.sinks.k1.hdfs.maxOpenFiles=5000 ? a1.sinks.k1.hdfs.fileType = DataStream ? a1.sinks.k1.hdfs.batchSize = 100 ? a1.sinks.k1.hdfs.writeFormat=Text ? a1.sinks.k1.hdfs.rollInterval = 60 ? a1.sinks.k1.hdfs.rollSize = 102400 ? a1.sinks.k1.hdfs.rollCount = 100000 ? a1.sinks.k1.hdfs.round = true ? a1.sinks.k1.hdfs.roundValue = 10 ? a1.sinks.k1.hdfs.roundUnit = minute ? a1.sinks.k1.hdfs.useLocalTimeStamp = true ? ? #配置channels ? a1.channels.c1.type=memory ? a1.channels.c1.keep-alive=120 ? a1.channels.c1.capacity=500000 ? a1.channels.c1.transactionCapacity=600 ? ? #绑定sink source到channels上 ? a1.sources.r1.channels=c1 ? a1.sinks.k1.channel=c1 ? 新建一个cmd窗口,输入如下命令启动zookeeper: ? > cd C:\kafka_2.12-2.4.0 ? > .\bin\windows\zookeeper-server-start.bat .\config\zookeeper.Properties ? 打开一个新的cmd窗口,输入如下命令启动Kafka: ? > cd C:\kafka_2.12-2.4.0 ? > .\bin\windows\kafka-server-start.bat .\config\server.properties ? 再打开一个新的cmd窗口创建Kafka的topic: ? > cd C:\kafka_2.12-2.4.0 ? > .\bin\windows\kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic flume ? 创建完成之后创建Kafka生产者: ? > cd C:\kafka_2.12-2.4.0 ? > .\bin\windows\kafka-console-producer.bat --broker-list localhost:9092 --topic flume ? 打开新的cmd窗口开启HDFS: ? > cd C:\hadoop-3.1.3\sbin ? > start-dfs.cmd ? 这时会弹出namenode和datanode窗口,不要关闭 ? 在新的cmd窗口启动flume: ? > cd C:\apache-flume-1.9.0-bin ? > .\bin\flume-ng agent --conf .\conf --conf-file .\conf\Ekafka2hdfs.conf --name a1 -property flume.root.logger=INFO,console ? 在启动生产者的窗口中输入“HelloFlume”。 ? 然后,打开浏览器输入“http://localhost:9870/explorer.html#”,查看HDFS中的文件,结果应如下:
基本题二:使用Flume写入当前文件系统 假设有一个目录“C:/mylog/”,现在新建两个文本文件1.txt与2.txt,在1.txt中输入“Hello Flume”,在2.txt中输入“hello flume”,请使用Flume对目录“C:/mylog/”进行监控,当把文件1.txt与2.txt放入该目录时,Flume就会把文件内容写入到“C:/backup”目录下的文件中。(注:配置文件中Source的类型为spooldir,Sink的类型为file_roll,具体用法可以参考文档:https://flume.apache.org/releases/content/1.9.0/FlumeUserGuide.html)
【参考答案】 Flume配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ? #文件名Efile2file.conf ? #设置名称 ? a1.sources=r1 ? a1.sinks=k1 ? a1.channels=c1 ? ? #配置Source ? a1.sources.r1.type=spooldir ? a1.sources.r1.spoolDir=C:/mylog/ ? ? #配置Sink ? a1.sinks.k1.type = file_roll ? a1.sinks.k1.channel = c1 ? a1.sinks.k1.sink.directory = C:/backup ? ? #配置channels ? a1.channels.c1.type=memory ? a1.channels.c1.capacity=1000 ? a1.channels.c1.transactionCapacity=100 ? ? #绑定sink source到channels上 ? a1.sources.r1.channels=c1 ? a1.sinks.k1.channel=c1 ? 在C盘创建两个目录,即mulog以及backup,再按要求创建两个txt文件,即1.txt和2.txt。 ? 打开一个cmd窗口启动Flume,命令如下: ? > cd C:\apache-flume-1.9.0-bin ? > .\bin\flume-ng agent --conf .\conf --conf-file .\conf\Efile2file.conf --name a1 -property flume.root.logger=INFO,console ? 将1.txt和2.txt拖入mylogs目录中,然后查看backup目录中的文件,可以看到如下结果:
pandas数据清洗初级实践 基本题一 基础练习 (1)根据列表[“Python”,”C”,”Scala”,”Java”,”GO”,”Scala”,”SQL”,”PHP”,”Python”]创建一个变量名为language的Series; 1 2 3 4 ? >>> import pandas as pd ? >>> import numpy as np ? >>> from pandas import DataFrame, Series ? >>> language = Series(["Python","C","Scala","Java","GO","Scala","SQL","PHP","Python"])
(2)创建一个由随机整型组成的Series,要求长度与language相同,变量名为score; 1 ? >>> score = Series(np.random.randint(10, size = (9,)))
(3)根据language和score创建一个DataFrame; 1 2 3 4 5 6 7 8 9 10 11 12 ? >>> df = DataFrame({'language':language, score':score}) ? >>> df ? language score ? 0 Python 8 ? 1 C 6 ? 2 Scala 8 ? 3 Java 4 ? 4 GO 9 ? 5 Scala 8 ? 6 SQL 5 ? 7 PHP 1 ? 8 Python 1
(4)输出该DataFrame的前4行数据; 1 2 3 4 5 6 ? >>> df.head(4) ? language score ? 0 Python 8 ? 1 C 6 ? 2 Scala 8 ? 3 Java 4
(5)输出该DataFrame中language字段为Python的行; 1 2 3 4 ? >>> df[df.language == 'Python'] ? language score ? 0 Python 8 ? 8 Python 1
(6)将DataFrame按照score字段的值进行升序排序; 1 2 3 4 5 6 7 8 9 10 11 12 ? >>> df.sort_values('score',inplace=True) ? >>> df ? language score ? 7 PHP 1 ? 8 Python 1 ? 3 Java 4 ? 6 SQL 5 ? 1 C 6 ? 0 Python 8 ? 2 Scala 8 ? 5 Scala 8 ? 4 GO 9
(7)统计language字段中每种编程语言出现的次数。 1 2 3 4 5 6 7 8 ? >>> df.language.value_counts() Scala 2 ? Python 2 ? PHP 1 ? GO 1 ? SQL 1 ? C 1 ? Java 1 ? Name: language, dtype: int64
2. 酒类消费数据 1) 用pandas将酒类消费数据表中的数据读取为DataFrame,输出包含缺失值的行;
1 2 3 4 ? >>> import pandas as pd ? >>> df = pd.read_csv('D:\drinks.csv') ? >>> df.loc[df.continent.isnull()].index ? Int64Index([ 5, 11, 14, 17, 32, 41, 43, 50, 51, 54, 68, 69, 73, 74, 84, 109, 122, 130, 143, 144, 145, 174, 184], dtype='int64')
2) 在使用read_csv函数读取酒类消费数据表时(除文件地址外不添加额外的参数),pandas将continent字段中的“NA”(代表北美洲,North American)自动识别为NaN。因此,需要将continent字段中的NaN全部替换为字符串NA。如果学有余力,可以自行在网络上调研如何在read_csv函数中添加参数使NA不被识别为NaN;
1 2 3 4 ? >>> # 直接全部替换为’NA’ ? >>> df = df.fillna('NA') ? >>> # 或者在读取数据时加入参数keep_default_na=False ? >>> df = pd.read_csv('D:\drinks.csv', keep_default_na=False)
3) 分别输出各个大洲的平均啤酒、烈酒和红酒的消费量;
1 2 3 4 5 6 7 8 9 ? >>> df.groupby('continent')[['beer_servings', 'spirit_servings', 'wine_servings']].mean() ? beer_servings spirit_servings wine_servings ? continent ? AF 61.471698 16.339623 16.264151 ? AS 37.045455 60.840909 9.068182 ? EU 193.777778 132.555556 142.222222 ? NA 145.434783 165.739130 24.521739 ? OC 89.687500 58.437500 35.625000 ? SA 175.083333 114.750000 62.416667
4) 分别输出啤酒、烈酒和红酒消费量最高的国家。
1 2 3 4 5 6 ? >>> df.iloc[df.beer_servings.argmax(), 0] ? 'Namibia' ? >>> df.iloc[df.spirit_servings.argmax(), 0] ? 'Grenada' ? >>> df.iloc[df.wine_servings.argmax(), 0] ? 'France'
3. 狗狗币的历史价格 1) 用pandas将历史价格表中的数据读取为DataFrame,并查看各个列的数据类型。在读取数据时,pandas是否将表中的日期字段自动读取为日期类型?若否,则将其转换为日期类型;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ? >>> import pandas as pd ? >>> df = pd.read_csv('D:\DOGE-USD.csv') ? >>> df.dtypes Date object ? Open float64 ? High float64 ? Low float64 ? Close float64 ? Volume float64 dtype: object ? >>> # 可见Date字段不是日期类型 ? >>> df.Date = pd.to_datetime(df.Date) ? >>> df.dtypes ? Date datetime64[ns] ? Open float64 ? High float64 ? Low float64 ? Close float64 ? Volume float64 ? dtype: object
2) 该DataFrame中是否存在缺失值?若是,则输出数据缺失的日期,并用前一交易日的数据填充缺失值;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 ? >>> df.info() ? <class 'pandas.core.frame.DataFrame'> ? RangeIndex: 2358 entries, 0 to 2357 ? Data columns (total 6 columns): ? Date 2358 non-null datetime64[ns] ? Open 2354 non-null float64 ? High 2354 non-null float64 ? Low 2354 non-null float64 ? Close 2354 non-null float64 ? Volume 2354 non-null float64 ? dtypes: datetime64[ns](1), float64(5) ? memory usage: 110.7 KB ? >>> # 可见除了Date字段外,其余字段都存在缺失值 ? >>> df['Date'].loc[df['Open'].isnull()] ? 2039 2020-04-17 ? 2214 2020-10-09 ? 2217 2020-10-12 ? 2218 2020-10-13 ? Name: Date, dtype: datetime64[ns] ? >>> df['Date'].loc[df['Close'].isnull()] ? 2039 2020-04-17 ? 2214 2020-10-09 ? 2217 2020-10-12 ? 2218 2020-10-13 ? Name: Date, dtype: datetime64[ns] ? >>> df['Date'].loc[df['High'].isnull()] ? 2039 2020-04-17 ? 2214 2020-10-09 ? 2217 2020-10-12 ? 2218 2020-10-13 ? Name: Date, dtype: datetime64[ns] ? >>> df['Date'].loc[df['Low'].isnull()] ? 2039 2020-04-17 ? 2214 2020-10-09 ? 2217 2020-10-12 ? 2218 2020-10-13 ? Name: Date, dtype: datetime64[ns] ? >>> df['Date'].loc[df['Volume'].isnull()] ? 2039 2020-04-17 ? 2214 2020-10-09 ? 2217 2020-10-12 ? 2218 2020-10-13 ? Name: Date, dtype: datetime64[ns] ? >>> # 可见存在缺失值的日期有四个 ? >>> df = df.fillna(method='pad')
3) 分别输出狗狗币价格的最高值与最低值,并分别输出达到最高值与最低值的日期;
1 2 3 4 5 6 7 8 >>> df.High.max() ? 0.084945 ? >>> df.Low.min() ? 8.499999999999999e-05 ? >>> df['Date'].loc[df['High'].argmax()] ? Timestamp('2021-02-08 00:00:00') ? >>> df['Date'].loc[df['Low'].argmin()] ? Timestamp('2015-05-07 00:00:00')
4) 画出狗狗币每天最高价格的折线图(横轴为日期);
1 2 3 4 ? >>> import matplotlib.pyplot as plt ? >>> plt.plot(df.Date, df.High) ? [<matplotlib.lines.Line2D object at 0x0000023AC49A0C48>] ? >>> plt.show() # 如图8-1所示
5) 画出狗狗币成交量的折线图(横轴为日期)。由于成交量字段中的数据数量级变化较大,直接画图无法直观地观察出其变化趋势,尝试画出更直观的成交量折线图(提示:取对数)。
1 2 3 4 5 ? >>> # 由于成交量的变化程度以及数量级较大 ? >>> # 因此考虑使用成交量的对数为纵轴 ? >>> plt.plot(df.Date, np.log10(df.Volume)) ? [<matplotlib.lines.Line2D object at 0x0000023AC49A0C48>] ? >>> plt.show() # 如图8-2示
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1401362462@qq.com
文章标题: exam2
字数: 3.5k
本文作者: 百xiao生
发布时间: 2023-12-11, 09:31:22
最后更新: 2023-12-15, 12:12:59
原始链接: https://baixiaoshengzjj.top/2023/12/11/exam2/
版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。