一、目标
新一届的全国大学生智能汽车竞赛开始了,想下载官网上的技术报告,看看大佬们在坐车时候的想法 ,然而官网的技术报告有点多,而且还没打包,得一个一个慢慢点击下载,下载速率太慢了,这不刚学了一下python爬虫吗,就想试试能不能使用python爬虫下载智能车竞赛官网的技术报告。
python 爬虫学习参见我的这篇文章
另外我的博客上也有上传
二、目标分析
1、技术报告的URL链接
打开官网,找到下载技术报告的页面,因为参赛的队伍比较多,优秀的队伍的技术报告也就多,所以官网将技术报告分到好几个页面中,点击一个选项组,2019-10-23 第十四届竞赛技术报告(6) 先找到一个要下载的技术报告,发现点击后就会下载,选中这个技术报告的名字,右键点击检查,查看网页代码,发现技术报告的下载地址就是 <a>...</a>
标签内 href 后面的链接,这样我们就找到了技术报告的链接地址了,但是一个页面中有那么多技术报告,不能一个一个填啊,所以我们就需要遍历查找这些 <a>...</a>
标签,从他的 href 属性中获得链接地址。
2、下载页面的URL
反过头查看下载页面的 URL 连接,发现这不就是竞赛官网的资料下载页面的 URL 吗?这咋和下载页面的 URL 一样?怎么网页地址没有变。得看一下到底指什么情况,检查一下网页代码,分析情况。
找到要下载的页面选项,将其选中,比如: 2019-10-23 第十四届竞赛技术报告(5) 选中后右键点击检查,查看源码。
发现这是 JavaScript 写的,void(0) 是一个点击不发生任何效果,停留在原地,称之为“死链接”,而我们想要的资源列表是在点击这段文字后出现的,那我们怎么的到还有技术报告的页面链接呢?这不是点击后跳转的吗,那就模拟人上网,用鼠标点击这个标签他不就过来了吗?然后经过查找,得出这个页面的连接放在 <iframe>...</iframe>
这么一个标签的 src 属性中。同样的方法测试别的下载页面都是一样的,所以下载页面的 URL 地址也就找到了。
三、开始写代码
1、获取下载页面的URL
前面分析我们知道,下载页面是 JavaScript:void(0) 实现的一个死链接,真正的连接在点击资料下载页面相应的文字后加载到新的资源页面后,在一个 <iframe>...</iframe>
标签的 src 属性里。我们要获得真正的下载页面的 URL 地址需要模拟鼠标点击,所以我们使用 selenium 模块中的 webdriver,所以先将模块导入。
1 | from selenium import webdriver |
接下来就快开始构建一个浏览器对象,使用无头浏览器模拟点击各个标签获取到下载页面的地址先保存起来。
1 | def geturl(begainurl, href): |
2、获取技术报告的URL
得到每个下载页面的 URL 后我们需要从每个下载页面得到技术报告的 URL 链接,这些链接才是我们真正下载时候需要的页面,通过前面分析,技术报告的 URL 链接在 <a>...</a>
标签的 href 属性中。遍历我们保存的下载页面的 URL ,访问这些 URL 获取到每个页面的网页代码,从中在遍历查找 <a>...</a>
标签,获取到技术报告的 URL 。
遍历下载页面的 URL ,获得每一页的网页源代码
1 | def getHTMLText(href, html): |
遍历获得到的网页源代码,从 <a>...</a>
标签获取到技术报告的 URL
1 | def getHref(html, url): |
3、筛选得到的URL
参看每个下载页面的内容发现,其实每个下载页面的内容挺乱的,出了要下载的技术报告外,里面还有像车模检查表、参赛证明、车模照片、电路图等,特别乱,像车模检查表这些我们都不需要,所以我们得将其筛选出去
1 | def hrefNmae(url): |
筛选过后差不多就是我们想要的了,不包括玩我的筛选问题,将一部分技术报告筛选出去的,因为太多我也没法查看,另外还有些文件名称命名比较模糊的,不知道是技术报告还是其他的什么东西的我没有进行排除,你们也可以自己尝试,因为正则表达式我感觉有点麻烦,所以我就通过保存的链接的字典中键值对进行了筛选,可能误差比较大。
4、获得技术报告
得到我们想要的技术报告的 URL 连接后我们就需要将其下载下来进行保存,这里我新建了一个文件夹,将其保存在里面。
1 | def getfiles(url): |
5、开始下载
这样就开始下载了,下载的时候会在 python 文件所在目录新建一个 技术报告 的文件夹,下载的技术报告就会保存的那,另外中间我也尝试用多线程去跑,但我添加上之后出现问题,没法运行也就放弃了,大家可以自己尝试一下
四、总结
第一次使用爬虫下载自己想要的东西,很开心,虽然中间遇到了很多困难,但都一一解决了,唯一没有解决的是多线程问题,接下来会好好研究一下,争取攻破。
五、完整代码
1 | import requests |