网络爬虫项目实战 教案汇 何福男 项目2-8 购物Scrapy项目实战 -社交Selenium项目实战_第1页
网络爬虫项目实战 教案汇 何福男 项目2-8 购物Scrapy项目实战 -社交Selenium项目实战_第2页
网络爬虫项目实战 教案汇 何福男 项目2-8 购物Scrapy项目实战 -社交Selenium项目实战_第3页
网络爬虫项目实战 教案汇 何福男 项目2-8 购物Scrapy项目实战 -社交Selenium项目实战_第4页
网络爬虫项目实战 教案汇 何福男 项目2-8 购物Scrapy项目实战 -社交Selenium项目实战_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

苏州工业职业技术学院SuzhouInstituteOfIndustrialTechnology第

PAGE

4页教师备课首页苏州工业职业技术学院教师备课首页SuzhouInstituteOfIndustrialTechnology第1页课题项目二购物Scrapy项目实战课型理实一体授课班级大数据22C1、大数据22C2授课时数10教学目标(1)掌握Scrapy项目搭建。(2)掌握XPath语法格式。(3)掌握从CSV文件读取到DataFrame。(4)掌握DataFrame去重方法。(5)掌握DataFrame列裂变。(6)掌握DataFrame自定义函数转换数据。(7)掌握DataFrame保存到CSV文件。(8)掌握DataFrame分组sum统计。(9)了解Series.str.match函数过滤DataFrame。(10)了解ECharts柱状图。教学重点(1)掌握Scrapy项目搭建。(2)掌握XPath语法格式。教学难点XPath语法格式学情分析学生零基础,在教学中注重引导学生学会自主学习,培养学生学会查找文献资料教学效果教后记任务1:Scrapy+XPath采集数据Scrapy是一个基于Twisted的异步处理框架,是纯Python实现的爬虫框架。Scrapy功能非常强大,爬取效率高,相关扩展组件丰富,可配置和可扩展程度非常高,是目前Python中使用最广泛的爬虫框架。XPath,全程为XMLPathLanguage,即XML路径语言,是一门在XML文档中查找信息的语言。XPath的选择功能十分强大,它提供了非常简洁明了的路径选择表达式。在做爬虫时,完全可以使用XPath来做相应的信息抽取。下面以爬取某购物网站为例,介绍Scrapy配合XPath采集手机销售数据的详细步骤。步骤1:转到Tomcat安装目录下的bin目录,运行startup.bat后,打开Chrome,访问:50001/cellphone/list.html,显示网站首页,代表Tomcat运行正常。步骤2:打开AnacondaPrompt,用下面命令转到PyCharm项目主目录(比如,D:\PycharmProjects):>cdD:\PycharmProjects>d:步骤3:用下面命令创建Scrapy空项目phonecrawler。>scrapystartprojectphonecrawler输出应该出现下面结果:NewScrapyproject'phonecrawler',usingtemplatedirectory'd:\users\lenovo\anaconda3\lib\site-packages\scrapy\templates\project',createdin:D:\PycharmProjects\phonecrawlerYoucanstartyourfirstspiderwith:cdphonecrawlerscrapygenspiderexample步骤4:转到phonecrawler子目录,执行下面命令创建爬虫。其中,phone_spider是爬虫名称,是网站域名。>cdphonecrawler>scrapygenspiderphone_spider输出应该出现下面结果:Createdspider'phone_spider'usingtemplate'basic'inmodule:phonecrawler.spiders.phone_spider步骤5:打开PyCharm,File->Open打开项目phonecrawler,展开项目主目录下的子目录phonecrawler。步骤6:打开File->Settings->ProjectInterpreter,选择第1章安装的AnacondaPython编译器。步骤7:修改phonecrawler/spiders/phone_spider.py,设置起始URL指向网站首页。#-*-coding:utf-8-*-importscrapyclassPhoneSpiderSpider(scrapy.Spider):name='phone_spider'allowed_domains=['']start_urls=[':50001/cellphone/list.html']defparse(self,response):pass步骤8:在项目根目录下New->PythonFile,创建startpoint.py,代码如下:#encoding=utf-8fromscrapyimportcmdlineRUN_SCRAPY_COMMAND='scrapycrawlphone_spider-ophone_raw.csv'.split('')#注意:用1个空格分隔cmdline.execute(RUN_SCRAPY_COMMAND)运行startpoint.py,控制台输出结果应该如下:2022-07-0808:36:28[scrapy.utils.log]INFO:Scrapy1.8.0started(bot:phonecrawler)2022-07-0808:36:28[scrapy.utils.log]INFO:Versions:lxml,libxml22.9.5,cssselect1.1.0,parsel1.5.2,w3lib1.21.0,Twisted18.7.0,Python3.7.0(default,Jun282018,08:04:48)[MSCv.191264bit(AMD64)],pyOpenSSL18.0.0(OpenSSL1.0.2p14Aug2018),cryptography2.3.1,PlatformWindows-10-10.0.19041-SP02022-07-0808:36:28[scrapy.crawler]INFO:Overriddensettings:{'BOT_NAME':'phonecrawler','FEED_FORMAT':'csv','FEED_URI':'phone_raw.csv','NEWSPIDER_MODULE':'phonecrawler.spiders','ROBOTSTXT_OBEY':True,'SPIDER_MODULES':['phonecrawler.spiders']}2022-07-0808:36:28[scrapy.extensions.telnet]INFO:TelnetPassword:21a06c7a9bd5d8032022-07-0808:36:28[scrapy.core.engine]INFO:Spideropened2022-07-0808:36:28[scrapy.extensions.logstats]INFO:Crawled0pages(at0pages/min),scraped0items(at0items/min)2022-07-0808:36:28[scrapy.extensions.telnet]INFO:Telnetconsolelisteningon:60232022-07-0808:36:28[scrapy.core.engine]DEBUG:Crawled(404)<GET:50001/robots.txt>(referer:None)2022-07-0808:36:28[protego]DEBUG:Ruleatline1withoutanyuseragenttoenforceiton.2022-07-0808:36:28[scrapy.core.engine]DEBUG:Crawled(200)<GET:50001/cellphone/list.html>(referer:None)2022-07-0808:36:28[scrapy.core.engine]INFO:Closingspider(finished)2022-07-0808:36:28[scrapy.core.engine]INFO:Spiderclosed(finished)从运行结果可以看出,爬虫先访问robots.txt,检查网站的限制,然后访问起止URL,接受服务器返回的页面内容。因为模拟网站上:50001/robots.txt不存在,服务器返回404状态码,HTTP状态码定义下文有解释。步骤9:修改phonecrawler/items.py,PhonecrawlerItem类添加商品名称、评论数、经销商属性。#-*-coding:utf-8-*-#Defineherethemodelsforyourscrapeditems##Seedocumentationin:#/en/latest/topics/items.htmlimportscrapyclassPhonecrawlerItem(scrapy.Item):#商品名称商品名称=scrapy.Field()#评价数量评价数量=scrapy.Field()#经销商经销商=scrapy.Field()步骤10:打开:50001/cellphone/list.html,在页面任意位置点击鼠标右键后,选择“检查”,选择“Network”选项卡,查看HTTP请求和返回内容。点击“Clear”按钮,清除缓存,然后在左面页面窗口中任意位置点击鼠标右键,选择“重新加载”。接着,切换到”Doc”选项卡后,选择”list.html”,查看RequestHeaders,保存User-Agent、cookie(如果有的话)、referer(如果有的话)3个属性值。步骤11:反注释phonecrawler/settings.py中DEFAULT_REQUEST_HEADERS部分,设置User-Agent。cookie和referer为空,不需要设置。DEFAULT_REQUEST_HEADERS={'User-Agent':'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/100.0.4896.127Safari/537.36'}步骤12:回到网站首页,然后点击鼠标右键,选择“检查”,在右边“Elements”窗口查找div元素,对照左边窗口的显示,找到各商品对应的页面元素。商品div的XPath相对路径为div[@class='product-box')],注意“product_box”以空格结尾。为了兼容前面或后面有多余空格的情况,指定商品对应页面元素的XPath路径为div[contains(@class,'product-box')],contains函数判断class属性值是否包含“product-box”。步骤13:鼠标停留在左面页面窗口中第1件商品的评价数量,然后点击鼠标右键后,选择“检查”,查找评价数量的XPath路径。从XPath路径为div[contains(@class,'product-box')]的元素开始,评价数量对应的XPath相对路径为“div[@class='res-info']/div/div[@class='info-evaluate']/a/i/text()”。步骤14:鼠标停留在左面窗口第4件商品的经销商,然后点击鼠标右键,选择“检查”,查找经销商的XPath路径。鼠标停留在左面窗口第8件商品的经销商,然后点击鼠标右键,选择“检查”,查找经销商的XPath路径。从XPath路径“div[contains(@class,'product-box')]”开始,经销商对应的XPath相对路径为“div[@class='res-info']/div/a[contains(@class,'store-class')]/text()”或“div[@class='res-info']/div/a[contains(@class,'store-name')]/text()”。综合2种路径,相对路径为“div[@class='res-info']/div/a[contains(@class,'store-class')orcontains(@class,'store-name')]/text()”。步骤15:类似上述步骤,查找商品名称的XPath路径,商品名称对应的XPath相对路径为“div[@class='res-info']/div[@class='title-selling-point']/a/text()”。步骤16:修改phonecrawler/spiders/phone_spider.py,爬取网站首页。#-*-coding:utf-8-*-importreimportscrapyfromphonecrawler.itemsimportPhonecrawlerItemclassPhoneSpiderSpider(scrapy.Spider):name='phone_spider'allowed_domains=['']start_urls=[':50001/cellphone/list.html']defparse(self,response):node_list=response.xpath("//div[contains(@class,'product-box')]")fornodeinnode_list:item=PhonecrawlerItem()#商品名字name=node.xpath("./div[@class='res-info']/div[@class='title-selling-point']/a/text()").extract()#数据保护name=name[0]iflen(name)>0else""#替换连续空格到单个空格item['商品名称']=re.sub("\s+","",name)#评价数量volume=node.xpath("./div[@class='res-info']/div/div[@class='info-evaluate']/a/i/text()").extract()#数据保护item['评价数量']=volume[0]iflen(volume)>0else""#经销商brand=node.xpath("./div[@class='res-info']/div/a[contains(@class,'store-class')orcontains(@class,'store-name')]/text()").extract()#数据保护item['经销商']=brand[0]iflen(brand)>0else""#详情URLyielditem运行startpoint.py,应该看到文件phone_raw.csv。打开phone_raw.csv,看到如下结果:商品名称,经销商,评价数量vivoiQOO7传奇12+256G高通骁龙888+增强版LPDDR5120W超快闪充全感操控系统双路线性马达立体双扬UFS3.1双模5G全网通手机,自营,8700+vivoiQOONeo58+256G夜影黑5G新品,柠悦数码旗舰店,1.1万+AppleiPhone12ProMax,自营,4.9万+荣耀30Pro,自营,6.0万+荣耀荣耀V40轻奢版,自营,3.4万+华为Mate40Pro4G,自营,1.2万+vivovivoiQOONeo58+256GB夜影黑5G新品手机,柠悦数码旗舰店,1.1万+vivovivoiQOONeo512+256GB云影蓝5G新品手机,柠悦数码旗舰店,1.1万+vivovivoiQOONeo512+256GB像素橙5G新品手机,柠悦数码旗舰店,1.1万+AppleiPhone12128G白色移动联通电信5G全网通,自营,21万+除第1行列名,2~11行是手机记录,恰好是1页数据,接下来继续增强爬虫,让它具有翻页爬取功能。步骤17:回到网站首页,滑动页面到最底端,鼠标停留在页码“2”,然后点击鼠标右键后,选择“检查”,查看页码“2”的XPath路径。页码“2”对应的XPath路径为“//div[@id="bottom_pager"]/div/a[last()]/text()”,“//”代表任意路径。步骤18:完善phonecrawler/spiders/phone_spider.py,定义list_base_url和offset,start_urls改变为可替换的模板,使爬虫具有翻页爬取功能。#-*-coding:utf-8-*-importreimportscrapyfromphonecrawler.itemsimportPhonecrawlerItemclassPhoneSpiderSpider(scrapy.Spider):name='phone_spider'allowed_domains=['']list_base_url=":50001/cellphone/list#offset#.html"offset=0#页码偏移量start_urls=[list_base_url.replace("#offset#","")]defparse(self,response):#更新最大页码ifself.offset==0:page_num=response.xpath('//div[@id="bottom_pager"]/div/a[last()]/text()').extract()[0]#数据保护self.max_pages=(int)(page_num)iflen(page_num)>0else0node_list=response.xpath("//div[contains(@class,'product-box')]")fornodeinnode_list:item=PhonecrawlerItem()#商品名字name=node.xpath("./div[@class='res-info']/div[@class='title-selling-point']/a/text()").extract()#数据保护name=name[0]iflen(name)>0else""#替换连续空格到单个空格item['商品名称']=re.sub("\s+","",name)#评价数量volume=node.xpath("./div[@class='res-info']/div/div[@class='info-evaluate']/a/i/text()").extract()#数据保护item['评价数量']=volume[0]iflen(volume)>0else""#经销商brand=node.xpath("./div[@class='res-info']/div/a[contains(@class,'store-class')orcontains(@class,'store-name')]/text()").extract()#数据保护item['经销商']=brand[0]iflen(brand)>0else""#详情URLyielditem#页码偏移量加1self.offset+=1#未走到最后一页就继续爬取ifself.offset<self.max_pages:url=self.list_base_url.replace("#offset#",str(self.offset))yieldscrapy.Request(url,callback=self.parse)运行startpoint.py,打开phone_raw.csv。打开文件,看到如下结果:商品名称,经销商,评价数量vivoiQOO7传奇12+256G高通骁龙888+增强版LPDDR5120W超快闪充全感操控系统双路线性马达立体双扬UFS3.1双模5G全网通手机,自营,8700+vivoiQOONeo58+256G夜影黑5G新品,柠悦数码旗舰店,1.1万+AppleiPhone12ProMax,自营,4.9万+荣耀30Pro,自营,6.0万+荣耀荣耀V40轻奢版,自营,3.4万+商品名称,经销商,评价数量vivoiQOO7传奇12+256G高通骁龙888+增强版LPDDR5120W超快闪充全感操控系统双路线性马达立体双扬UFS3.1双模5G全网通手机,自营,8700+vivoiQOONeo58+256G夜影黑5G新品,柠悦数码旗舰店,1.1万+AppleiPhone12ProMax,自营,4.9万+荣耀30Pro,自营,6.0万+荣耀荣耀V40轻奢版,自营,3.4万+【赠1年碎屏险】OPPOK7x黑镜6G+128G30W闪充双模5G手机全网通手机拍照手机游戏手机oppok7xoppo手机oppok7x,OPPO官方旗舰店,2200+三星GalaxyA515G(SM-A5160)8GB+128GB迷踪黑SuperAMOLED屏后置四摄3200万前置移动联通电信全网通5G手机,自营,7700+苹果(Apple)iPhone11128GB黑色简配版移动联通电信4G全网通手机(不含电源适配器和耳机)双卡双待iphone112020新款,华科手机专营店,1.2万+康佳(KONKA)UK8直板老人机大字大声大屏超长待机老年手机男女款移动双卡双待按键学生备用功能机,自营,7400+【购机送1年碎屏保】OPPOA8天青色4GB+128GB新品手机6.5英寸水滴屏4230mAh大电池后置AI三摄全网通4G全面屏拍照游戏智能手机oppoa8手机,时器数码专营店,2600+任务2:Pandas清洗数据phone_raw.csv前11行记录是重复数据,需要删除。另外,字段“评价数”的后缀“万+”需要转换到10进制数字,“+”后缀删除。接下来,采用Pandas完成数据清洗任务。步骤1:在项目根目录New->PythonFile,创建data_clean.py,读入phone_raw.csv到DataFrame类型。#encoding=utf-8importpandasaspd#读入CSV文件到Dataframe对象labels=["商品名称","经销商","评价数量"]df=pd.read_csv('phone_raw.csv',names=labels,encoding='utf-8')print(df.head())运行data_clean.py,PyCharm控制台输出如下结果:商品名称经销商评价数量0商品名称经销商评价数量1vivoiQOO7传奇12+256G高通骁龙888+增强版LPDDR5120W超...自营8700+2vivoiQOONeo58+256G夜影黑5G新品柠悦数码旗舰店1.1万+3AppleiPhone12ProMax自营4.9万+4荣耀30Pro自营6.0万+步骤2:完善data_clean.py,忽略DataFrame包含的CSV头。#删除第2次爬取生成的csv头df=df[df["评价数量"]!="评价数量"]print(df.head(5))运行data_clean.py,PyCharm控制台输出如下结果:商品名称经销商评价数量1vivoiQOO7传奇12+256G高通骁龙888+增强版LPDDR5120W超...自营8700+2vivoiQOONeo58+256G夜影黑5G新品柠悦数码旗舰店1.1万+3AppleiPhone12ProMax自营4.9万+4荣耀30Pro自营6.0万+5荣耀荣耀V40轻奢版自营3.4万+步骤3:完善data_clean.py,删除重复记录。#去重df=df.drop_duplicates()print("去重后记录行数:{}".format(df.shape[0]))运行data_clean.py,PyCharm控制台输出如下结果:去重后记录行数:19步骤4:完善data_clean.py,建立包含“评价数量”、“单位”列的DataFrame。#字段“评价数量”裂变成两列:评价数(数字),单位pattern="(?P<评价数>\d+\.?\d*)(?P<单位>.?\+)"comment_df=df["评价数量"].str.extract(pattern)print(comment_df.head())运行data_clean.py,PyCharm控制台输出如下结果:评价数量单位18700+21.1万+34.9万+46.0万+53.4万+步骤5:完善data_clean.py,根据字段“单位”计算十进制的评价数。#去除评价数量后面的单位defextract_salary(x):ifx["单位"]=="万+":salary=int(eval(x["评价数"])*10000)else:salary=(int)(eval(x["评价数"]))returnsalary#应用extract_salary处理comment_df的每一行comment_df["评价数"]=comment_df.apply(extract_salary,axis=1)#更新原始DataFrame的字段“评价数”df["评价数量"]=comment_df["评价数"]print(df.head())运行data_clean.py,PyCharm控制台输出如下结果:商品名称经销商评价数量1vivoiQOO7传奇12+256G高通骁龙888+增强版LPDDR5120W超...自营87002vivoiQOONeo58+256G夜影黑5G新品柠悦数码旗舰店110003AppleiPhone12ProMax自营490004荣耀30Pro自营600005荣耀荣耀V40轻奢版自营34000步骤6:完善data_clean.py,保存清洗后的数据。#保存清洗后的数据df.to_csv("phone_clean.csv",index=False)打开phone_raw.csv,看到如下结果:商品名称,经销商,评价数量vivoiQOO7传奇12+256G高通骁龙888+增强版LPDDR5120W超快闪充全感操控系统双路线性马达立体双扬UFS3.1双模5G全网通手机,自营,8700vivoiQOONeo58+256G夜影黑5G新品,柠悦数码旗舰店,11000AppleiPhone12ProMax,自营,49000荣耀30Pro,自营,60000荣耀荣耀V40轻奢版,自营,34000华为Mate40Pro4G,自营,12000vivovivoiQOONeo58+256GB夜影黑5G新品手机,柠悦数码旗舰店,11000vivovivoiQOONeo512+256GB云影蓝5G新品手机,柠悦数码旗舰店,11000vivovivoiQOONeo512+256GB像素橙5G新品手机,柠悦数码旗舰店,11000AppleiPhone12128G白色移动联通电信5G全网通,自营,210000OPPOK9幻彩之翼8+256G高通骁龙768G65W超级闪充90HzOLED电竞屏6400万AI三摄双模5G全网通游戏拍照手机,自营,300小米Redmi10XPro,自营,9100华为畅享20SE,华科手机专营店,2200realme真我GTNeo5G数字移动电话机全网通版,自营,3900【赠1年碎屏险】OPPOK7x黑镜6G+128G30W闪充双模5G手机全网通手机拍照手机游戏手机oppok7xoppo手机oppok7x,OPPO官方旗舰店,2200三星GalaxyA515G(SM-A5160)8GB+128GB迷踪黑SuperAMOLED屏后置四摄3200万前置移动联通电信全网通5G手机,自营,7700苹果(Apple)iPhone11128GB黑色简配版移动联通电信4G全网通手机(不含电源适配器和耳机)双卡双待iphone112020新款,华科手机专营店,12000康佳(KONKA)UK8直板老人机大字大声大屏超长待机老年手机男女款移动双卡双待按键学生备用功能机,自营,7400【购机送1年碎屏保】OPPOA8天青色4GB+128GB新品手机6.5英寸水滴屏4230mAh大电池后置AI三摄全网通4G全面屏拍照游戏智能手机oppoa8手机,时器数码专营店,2600任务3:Pandas分析数据经过数据清洗后,采用Pandas按照经销商分组统计评价数。步骤1:在项目根目录New–>PythonFile,创建data_analysis.py,读入phone_clean.csv到DataFrame对象。#encoding=utf-8importpandasaspd#读入CSV文件到Dataframe对象df=pd.read_csv("phone_clean.csv",header=0,encoding="utf-8")print(df.head())运行data_analysis.py,PyCharm控制台输出如下结果:商品名称经销商评价数量0vivoiQOO7传奇12+256G高通骁龙888+增强版LPDDR5120W超...自营87001vivoiQOONeo58+256G夜影黑5G新品柠悦数码旗舰店110002AppleiPhone12ProMax自营490003荣耀30Pro自营600004荣耀荣耀V40轻奢版自营34000步骤2:完善data_analysis.py,记录按照经销商分组后,统计评价数。#分经销商统计评价数stats_stats=df.groupby(["经销商"]).sum()[["评价数量"]]print(stats_stats)运行data_analysis.py,PyCharm控制台输出如下结果:评价数量经销商OPPO官方旗舰店2200华科手机专营店14200时器数码专营店2600柠悦数码旗舰店44000自营402100有了上面的结果,手工复制到ECharts图表,完成可视化任务。任务3:ECharts可视化数据ECharts提供了多种图表,比如柱状图、饼形图、雷达图等,这里采用常见的柱状图对比手机经销商的关注度。步骤1:在项目根目录New->Directory,创建app目录。步骤2:在app目录下New->Directory,创建目录static,然后把echarts.min.js复制到app/static目录。步骤3:在app目录下New->Directory,创建templates目录。步骤4:在templates目录下NewHTMLFile,创建single_chart.html。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>单图</title></head><body></body></html>步骤5:在single_chart.html中引入依赖的JS文件。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>单图</title><scriptsrc="../static/echarts.min.js"></script></head><body></body></html>步骤6:完善single_chart.html,定义div元素和编写JS代码。JS代码中引用数据分析产生的数据,实例化ECharts图表对象,然后传给div元素显示。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>单图</title><scriptsrc="../static/echarts.min.js"></script></head><body><divid="chart1"style="float:left;width:600px;height:400px"></div><script>varmychart1=echarts.init(document.getElementById("chart1"));varxdata=["OPPO官方旗舰店","华科手机专营店","时器数码专营店","柠悦数码旗舰店","自营"];varydata=[2200,14200,2600,44000,402100];varoption={title:{text:'手机经销商关注度',x:'center',textStyle:{color:'red',fontWeight:'bold',fontSize:'20'}},tooltip:{trigger:'axis'},xAxis:[{type:'category',data:xdata,name:'',axisLabel:{interval:0,rotate:10}}],yAxis:{type:'value',name:'评价数'},series:[{type:'bar',name:xdata,data:ydata}]};mychart1.setOption(option);</script></body></html>鼠标移到single_chart.html编辑窗口的任意位置,出现浏览器浮动窗口。教师备课首页苏州工业职业技术学院教师备课首页SuzhouInstituteOfIndustrialTechnology第1页课题项目三招聘Requests项目实战课型理实一体授课班级大数据22C1、大数据22C2授课时数8教学目标(1)掌握Requests爬虫用法。(2)掌握XPath语法格式。(3)掌握从CSV文件读取到DataFrame。(4)掌握DataFrame去重方法。(5)掌握DataFrame列裂变。(6)掌握DataFrame自定义函数转换数据。(7)掌握DataFrame保存到CSV文件。(8)掌握DataFrame删除列。(9)掌握DataFrame分组count统计。(10)理解DataFrame分组mean统计。(11)了解ECharts柱状图。(12)了解ECharts饼状图。教学重点(1)掌握Requests爬虫用法。(2)掌握XPath语法格式。教学难点XPath语法格式学情分析学生零基础,在教学中注重引导学生学会自主学习,培养学生学会查找文献资料教学效果教后记任务1:Requests+XPath采集数据下面以爬取某招聘网站为例,介绍Requests配合XPath采集手机销售数据的详细步骤。步骤1:转到Tomcat安装目录下的bin目录,运行startup.bat后,打开Chrome,访问:50001/findjob/index1.html,显示网站首页,代表Tomcat运行正常。步骤2:打开PyCharm,File->NewProject创建PyCharm项目jobvis,手工填写项目路径,选择Anaconda编译器(python.exe),点击“Create”按钮,进入窗口“OpenProject”。点击“OK”按钮,创建空项目jobvis。步骤3:打开网站首页,在页面任意位置点击鼠标右键后,选择“检查”,选择“Network”选项卡,查看HTTP请求和返回内容。点击“Clear”按钮,清除缓存,然后在左面页面窗口中任意位置点击鼠标右键,选择“重新加载”。接着,切换到”Doc”选项卡后,选择”list1.html”,查看RequestHeaders,保存User-Agent、cookie(如果有的话)、referer(如果有的话)3个属性值。步骤4:在项目根目录下New->PythonFile,创建findjob_spider.py,定义get_page函数,起始URL指向网站首页,headers的“User-Agent”值使用上面RequestHeaders复制过来的内容。importcsvimportreimportrequestsfromlxmlimportetreefromrequests.utilsimportget_encodings_from_contentlist_base_url=":50001/findjob/index1.html"defget_page(url):#从chrome开发者工具复制User-Agent和cookie值(如果有的话)headers={'User-Agent':'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/91.0.4472.124Safari/537.36'}#发送GET请求res=requests.get(url,headers)#查看编码方式enconding=get_encodings_from_content(res.text)#打印网页内容html_doc=res.content.decode(enconding[0])returnhtml_doc步骤5:打开网站首页(:50001/findjob/index1.html),然后在页面空白区域点击鼠标右键,选择“检查”,在右边“Elements”窗口查找div元素,对照左边窗口的显示,找到各岗位div对应的页面元素岗位div的XPath相对路径为div[@class='j_joblist']/div[@class='e'],在爬虫中用这个相对路径匹配岗位div。步骤6:回到网站首页,鼠标停留在第1个岗位的职位名称,然后点击鼠标右键后,选择“检查”,查找职位名称的XPath路径。从XPath路径“div[@class='j_joblist']/div[@class='e']”开始,“职位名称”字段对应的XPath相对路径为“a/p/span[@class='jnameat']/text()”。步骤7:鼠标停留在左面窗口的单位名称,然后点击鼠标右键后,选择“检查”,找到单位名称的XPath路径。从XPath路径“div[@class='j_joblist']/div[@class='e']”开始,“岗位名称”字段对应的XPath相对路径为“div[@class='er']/a/text()”。步骤8:类似上述步骤,查找单位属性和发布时间的XPath路径。从XPath路径“div[@class='j_joblist']/div[@class='e']”开始,单位属性对应的XPath相对路径为“div[@class='er']/p[@class='dcat']/text()”,发布时间对应的XPath相对路径为“a/p/span[@class='time']/text()”。步骤9:在findjob_spider.py中增加parse_page和website_crawl函数,职位名称、单位名称、单位名称和发布时间使用上面查找的XPath路径。defparse_page(url):#解析页面到html树page_content=get_page(url)response=etree.HTML(page_content)#提取商品属性node_list=response.xpath("//div[@class='j_joblist']/div[@class='e']")fornodeinnode_list:#职位名称span_value=node.xpath("./a/p/span[@class='jnameat']/text()")iflen(span_value)>0:jobName=re.sub("\s+","",span_value[0])else:jobName=""#单位名称a_value=node.xpath("./div[@class='er']/a/text()")companyName=a_value[0]iflen(a_value)>0else""#单位属性,例:['国企|500-1000人']p_value=node.xpath("./div[@class='er']/p[@class='dcat']/text()")iflen(p_value)>0:companyAttr=re.sub("\s+","",p_value[0])else:companyAttr=""#发布时间,例:06-14发布span_value=node.xpath("./a/p/span[@class='time']/text()")pubTime=span_value[0]iflen(span_value)>0else""#保存职位信息withopen('findjob_raw.csv','a',newline="",encoding='utf-8')asf:csv_write=csv.writer(f)csv_write.writerow([jobName,companyName,companyAttr,pubTime])defwebsite_crawl():current_page_url=list_base_urlparse_page(current_page_url)步骤10:在findjob_spider.py定义主函数。if__name__=='__main__':website_crawl()运行findjob_spider.py,应该在项目根目录下看到文件findjob_raw.csv。打开findjob_raw.csv,看到如下结果:嵌入式硬件工程师,上海大唐移动通信设备有限公司,国企|500-1000人,06-14发布模拟电路工程师,上海磐诺仪器有限公司,民营公司|150-500人,06-14发布电子工程师(仪器研发),北京百晶生物技术有限公司,外资(非欧美)|少于50人,06-14发布高级硬件工程师,罗特尼克能源科技(北京)有限公司,合资|50-150人,06-14发布高级电气应用(调试)工程师,北京煜能电气有限公司,民营公司|少于50人,06-14发布硬件工程师,煜象科技(杭州)有限公司,民营公司,06-14发布电气设计工程师,华信永益(北京)信息技术有限公司,民营公司|500-1000人,06-14发布电子工程师,北京宝德仪器有限公司,民营公司|50-150人,06-14发布技术工程师(五险一金),广东柏高保设备工程有限公司,民营公司|50-150人,06-14发布电池管理工程师,蔚蓝空间飞行器有限公司,民营公司|少于50人,06-14发布仪表工程师,北京凯明阳热能技术有限公司,民营公司|少于50人,06-14发布电气技术员,北京金瀑布景观艺术有限责任公司,民营公司|少于50人,06-14发布嵌入式电气工程师,北京东孚久恒仪器技术有限公司,国企|50-150人,06-14发布电气工程技术员,北京中治赛瑞科技有限责任公司,民营公司|少于50人,06-14发布硬件工程师,北京宝盈科技发展有限公司,民营公司|少于50人,06-14发布上面结果显示15条记录,恰好是1页数据,接下来继续增强爬虫,让它具有翻页爬取功能。步骤11:回到网站首页,滑动页面到最底端,鼠标停留在最后一页的页码“5”,然后点击鼠标右键后,选择“检查”,查看页码“5”的XPath路径。页码“5”对应的XPath路径为“//div[@class="p_in"]/ul/li[last()-1]/a/text()”,“//”代表任意路径,“last()”代表最后一个li子结点,“last()-1”代表倒数第2个li子结点。步骤12:修改findjob_spider.py,定义list_base_url和offset,start_urls改变为可替换的模板,完善website_crawl函数,使爬虫具有翻页爬取功能。importrandomfromtimeimportsleeplist_base_url=":50001/findjob/index#offset#.html"defwebsite_crawl():#获取首页内容start_url=list_base_url.replace("#offset#",str(1))first_page_doc=get_page(start_url)first_page_tree=etree.HTML(first_page_doc)#找到总页数page_num=first_page_tree.xpath('//div[@class="p_in"]/ul/li[last()-1]/a/text()')page_num=(int)(page_num[0])iflen(page_num)>0else0ifpage_num:page_num=(int)(page_num)#访问所有页面foriinrange(1,page_num+1):current_page_url=list_base_url.replace("#offset#",str(i))#sleep(seconds)随机间隔5~10秒爬取页面,防止目标网站拦截sleep(random.randint(5,10)+random.random())print("爬取第{}页".format(i))parse_page(current_page_url)运行findjob_spider.py,打开findjob_raw.csv。打开文件,看到如下结果:嵌入式硬件工程师,上海大唐移动通信设备有限公司,国企|500-1000人,06-14发布模拟电路工程师,上海磐诺仪器有限公司,民营公司|150-500人,06-14发布电子工程师(仪器研发),北京百晶生物技术有限公司,外资(非欧美)|少于50人,06-14发布高级硬件工程师,罗特尼克能源科技(北京)有限公司,合资|50-150人,06-14发布高级电气应用(调试)工程师,北京煜能电气有限公司,民营公司|少于50人,06-14发布嵌入式硬件工程师,上海大唐移动通信设备有限公司,国企|500-1000人,06-14发布模拟电路工程师,上海磐诺仪器有限公司,民营公司|150-500人,06-14发布电子工程师(仪器研发),北京百晶生物技术有限公司,外资(非欧美)|少于50人,06-14发布高级硬件工程师,罗特尼克能源科技(北京)有限公司,合资|50-150人,06-14发布高级电气应用(调试)工程师,北京煜能电气有限公司,民营公司|少于50人,06-14发布模拟IC设计工程师,北京芯动致远微电子技术有限公司,民营公司,06-14发布模拟电路资深设计工程师,辰芯半导体(深圳)有限公司,民营公司|少于50人,06-14发布FAE现场应用工程师,北京维信诺光电技术有限公司,民营公司|50-150人,06-14发布任务2:Pandas清洗数据findjob_raw.csv包含90条记录,其中前15条是重复数据,需要删除。另外,要从页面字段“单位属性”中解析出单位类型。接下来,采用Pandas完成数据清洗任务。步骤1:在项目根目录New->PythonFile,创建data_clean.py,读入findjob_raw.csv到DataFrame类型。importpandasaspdlabels=["职位名称","单位名称","单位属性","发布时间"]df=pd.read_csv('findjob_raw.csv',names=labels,encoding='utf-8')print(df.head())运行data_clean.py,PyCharm控制台输出如下结果:职位名称单位名称单位属性发布时间0嵌入式硬件工程师上海大唐移动通信设备有限公司国企|500-1000人06-14发布1模拟电路工程师上海磐诺仪器有限公司民营公司|150-500人06-14发布2电子工程师(仪器研发)北京百晶生物技术有限公司外资(非欧美)|少于50人06-14发布3高级硬件工程师罗特尼克能源科技(北京)有限公司合资|50-150人06-14发布4高级电气应用(调试)工程师北京煜能电气有限公司民营公司|少于50人06-14发布步骤2:完善data_clean.py,删除重复记录。#去重df=df.drop_duplicates()print("去重后记录行数:{}".format(df.shape[0]))运行data_clean.py,PyCharm控制台输出如下结果:去重后记录行数:72步骤3:完善data_clean.py,从“单位属性”列抽取出单位类型和规模。#字段“单位属性”裂变成二列:单位类型,规模。pattern="(?P<单位类型>.+)\|(?P<规模>.+)"compdesc_df=df["单位属性"].str.extract(pattern)df["单位类型"]=compdesc_df["单位类型"]df["规模"]=compdesc_df["规模"]df.drop(["单位属性"],axis=1,inplace=True)print(df[["单位类型","规模"]].head())运行data_clean.py,PyCharm控制台输出如下结果:单位类型规模0国企500-1000人1民营公司150-500人2外资(非欧美)少于50人3合资50-150人4民营公司少于50人步骤4:完善data_clean.py,删除“发布时间”列的“发布”后缀。#字段“发布时间”去掉“发布”后缀。df["发布时间"]=df["发布时间"].str.replace("发布","")print(df["发布时间"].head())运行data_clean.py,PyCharm控制台输出如下结果:006-14106-14206-14306-14406-14步骤4:完善data_clean.py,保存清洗后的数据。#保存清洗后的数据df.to_csv("findjob_clean.csv",index=False)3.3.3任务3:Pandas分析数据经过数据清洗后,采用Pandas按照经销商分组统计评价数。步骤1:在项目根目录New–>PythonFile,创建data_analysis.py,读入findjob_clean.csv到DataFrame类型。importpandasaspd#读入csv文件到Dataframe对象df=pd.read_csv("findjob_clean.csv",header=0,encoding="utf-8")print(df.head())运行data_analysis.py,PyCharm控制台输出如下结果:职位名称单位名称发布时间单位类型规模0嵌入式硬件工程师上海大唐移动通信设备有限公司06-14国企500-1000人1模拟电路工程师上海磐诺仪器有限公司06-14民营公司150-500人2电子工程师(仪器研发)北京百晶生物技术有限公司06-14外资(非欧美)少于50人3高级硬件工程师罗特尼克能源科技(北京)有限公司06-14合资50-150人4高级电气应用(调试)工程师北京煜能电气有限公司06-14民营公司少于50人步骤2:完善data_analysis.py,记录按照单位类型分组后,统计招聘岗位数量。#按单位类型统计岗位数量stats_stats=df.groupby(["单位类型"]).count()[["职位名称"]].reset_index().rename(columns={"职位名称":"岗位数量"})print(stats_stats)运行data_analysis.py,PyCharm控制台输出如下结果:单位类型岗位数量0上市公司21合资262国企73外企代表处14外资(欧美)55外资(非欧美)46民营公司18有了上面的结果,手工复制到ECharts图表,完成可视化任务。3.3.4任务3:ECharts可视化数据ECharts提供了多种图表,比如柱状图、饼形图、雷达图等,这里采用常见的饼图对比各单位类型的岗位招聘数量比例。步骤1:在项目根目录New->Directory,创建app目录。步骤2:在app目录下New->Directory,创建目录static,然后把echarts.min.js复制到app/static目录。步骤3:在app目录下New->Directory,创建templates目录。步骤4:在templates目录下NewHTMLFile,创建single_chart.html。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>单图</title></head><body></body></html>步骤5:在single_chart.html中引入依赖的JS文件。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>单图</title><scriptsrc="../static/echarts.min.js"></script></head><body></body></html>步骤6:完善single_chart.html,定义div元素和编写JS代码。JS代码中引用数据分析产生的数据,实例化ECharts图表对象,然后传给div元素显示。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>单图</title><scriptsrc="../static/echarts.min.js"></script></head><body><divid="chart1"style="float:left;width:600px;height:400px"></div><script>varmychart1=echarts.init(document.getElementById("chart1"));varpie_data=[{value:2,name:"上市公司"},{value:26,name:"合资"},{value:7,name:"国企"},{value:1,name:"外企代表处"},{value:5,name:"外资(欧美)"},{value:4,name:"外资(非欧美)"},{value:18,name:"民营公司"}];varoption={title:{text:'各类型公司招聘岗位比例',x:'center',textStyle:{color:'red',fontWeight:'bold',fontSize:'20'}},series:[{type:'pie',//设置图表类型为饼图radius:'55%',//饼图的半径,外半径为可视区尺⼨(容器⾼宽中较⼩⼀项)的55%长度。data:pie_data}]};mychart1.setOption(option);</script></body></html>鼠标移到single_chart.html编辑窗口的任意位置,出现浏览器浮动窗口。选择Chrome打开single_chart.html,可视化结果如图3-2所示。教师备课首页苏州工业职业技术学院教师备课首页SuzhouInstituteOfIndustrialTechnology第1页课题项目四招聘Requests项目实战课型理实一体授课班级大数据22C1、大数据22C2授课时数8教学目标(1)掌握Scrapy爬虫框架用法。(2)掌握Xpath的用法。(3)掌握从CSV文件读取到DataFrame。(4)掌握DataFrame列裂变。(5)掌握DataFrame文字替换。(6)掌握DataFrame列数据类型转换。(7)掌握DataFrame保存到CSV文件。(8)掌握在数据库中新建数据表。(9)从CSV文件读取到MySQL数据表。(10)掌握MySQL查询数据表。(11)掌握Flask框架可视化图表。教学重点(1)掌握Scrapy爬虫用法。(2)掌握Flask框架可视化图表。教学难点Flas

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论