前言:因为自己还是python世界的一名小学生,还有很多路要走,所以本文以目的为向导,达到目的即可,对于那些我自己都没弄懂的原理,不做去做过多解释,以免误人子弟,大家可以网上搜索。

友情提示:本代码用到的网址仅供交流学习使用,如有不妥,请联系删除。

背景:自己有台电脑要给老爸用,老爷子喜欢看一些大片,但是家里网络环境不好,就想批量下载一些存到电脑里。但是目前大部分的网站都是这样的,

需要一个个地点进去,才能看到下载地址

如果我要下载100部电影,那肯定手都要点断了,于是便想把这些地址给爬取出来,迅雷批量下载。

工具:python(版本3.x)

爬虫原理:网页源代码中含有下载地址,把这些零散的地址批量保存到文件中,方便使用。

干货:首先上代码,迫不及待的你可以先运行一下,再看详细介绍。

  1. import requests
  2. import re
  3.  
  4. #changepage用来产生不同页数的链接
  5. def changepage(url,total_page):
  6. page_group = ['https://www.dygod.net/html/gndy/jddy/index.html']
  7. for i in range(2,total_page+1):
  8. link = re.sub('jddy/index','jddy/index_'+str(i),url,re.S)
  9. page_group.append(link)
  10. return page_group
  11. #pagelink用来产生页面内的视频链接页面
  12. def pagelink(url):
  13. base_url = 'https://www.dygod.net/html/gndy/jddy/'
  14. headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
  15. req = requests.get(url , headers = headers)
  16. req.encoding = 'gbk'#指定编码,否则会乱码
  17. pat = re.compile('<a href="/html/gndy/jddy/(.*?)" class="ulink" title=(.*?)/a>',re.S)#获取电影列表网址
  18. reslist = re.findall(pat, req.text)
  19.  
  20. finalurl = []
  21. for i in range(1,25):
  22. xurl = reslist[i][0]
  23. finalurl.append(base_url + xurl)
  24. return finalurl #返回该页面内所有的视频网页地址
  25.  
  26. #getdownurl获取页面的视频地址
  27. def getdownurl(url):
  28. headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
  29. req = requests.get(url , headers = headers)
  30. req.encoding = 'gbk'#指定编码,否则会乱码
  31. pat = re.compile('<a href="ftp(.*?)">ftp',re.S)#获取下载地址
  32. reslist = re.findall(pat, req.text)
  33. furl = 'ftp'+reslist[0]
  34. return furl
  35.  
  36. if __name__ == "__main__" :
  37. html = "https://www.dygod.net/html/gndy/jddy/index.html"
  38. print('你即将爬取的网站是:https://www.dygod.net/html/gndy/jddy/index.html')
  39. pages = input('请输入需要爬取的页数:')
  40. p1 = changepage(html,int(pages))
  41. with open ('电影天堂下载地址.lst','w') as f :
  42. j = 0
  43. for p1i in p1 :
  44. j = j + 1
  45. print('正在爬取第%d页,网址是 %s ...'%(j,p1i))
  46. p2 = pagelink(p1i)
  47. for p2i in p2 :
  48. p3 = getdownurl(p2i)
  49. if len(p3) == 0 :
  50. pass
  51. else :
  52. finalurl = p3
  53. f.write(finalurl + '\n')
  54. print('所有页面地址爬取完毕!')

核心模块getdownurl函数:通过requests来获取页面信息,可以认为这个信息的text就是页面源代码(几乎任何一款浏览器右键都有查看网页源代码的选项),再通过re.compile正则表达式匹配的方式来匹配到网页源代码中的网址部分,可以看下图

这部分怎么提取呢?通过正则表达式匹配。怎么写这个正则表达式呢?这里用到一个简单粗暴的方法:

<a href="ftp(.*?)">ftp

爬虫中经常用到.*?来做非贪婪匹配(专业名词请百度),你可以简单认为这个(.*?)就代表你想要爬取出来的东西,这样的东西在每个网页源码中都是夹在<a href="ftp和">ftp之间的。有人可能会问,那这个匹配出来的不是网址啊,比如上图中出来的就是://d:d@dygodj8.com:12311/[电影天堂www.dy2018.com]请以你的名字呼唤我BD中英双字.mp4,前面少了个ftp啊?

是的,不过这是故意为之,如果正则表达式写成<a href="(.*?)">ftp,可能夹在<a href="和">ftp之间的东西就太多了,二次处理的成本还不如先用你觉得最快最直接的方式抽取有用信息,然后再进行拼接来得快。

代码详解:

一、getdownurl

  1. #getdownurl获取页面的视频地址
  2. def getdownurl(url):
  3. headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
  4. req = requests.get(url , headers = headers)
  5. req.encoding = 'gbk'#指定编码,否则会乱码
  6. pat = re.compile('<a href="ftp(.*?)">ftp',re.S)#获取下载地址
  7. reslist = re.findall(pat, req.text)
  8. furl = 'ftp'+reslist[0]
  9. return furl

其中headers是用来将你的脚本访问网址伪装成浏览器访问,以防有些网站进行了反爬虫的措施。这个headers在很多浏览器中也可以很容易得到,以Firefox为例,直接F12或查看元素,在网络标签,右侧的消息头中右下角即可看到。

  1. requests模块:requests.get(url , headers = headers)是用伪装成firefox的形式获取该网页的信息。
    re模块:可以参考python正则表达式的一些东西,这里用re.complile来写出匹配的模式,re.findall根据模式在网页源代码中找到相应的东西。
    二、pagelink
  1. #pagelink用来产生页面内的视频链接页面
  2. def pagelink(url):
  3. base_url = 'https://www.dygod.net/html/gndy/jddy/'
  4. headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
  5. req = requests.get(url , headers = headers)
  6. req.encoding = 'gbk'#指定编码,否则会乱码
  7. pat = re.compile('<a href="/html/gndy/jddy/(.*?)" class="ulink" title=(.*?)/a>',re.S)#获取电影列表网址
  8. reslist = re.findall(pat, req.text)
  9.  
  10. finalurl = []
  11. for i in range(1,25):
  12. xurl = reslist[i][0]
  13. finalurl.append(base_url + xurl)
  14. return finalurl #返回该页面内所有的视频网页地址

第一步getdownurl是用于爬取一个网页的网址,这一步用于获取同一页面内所有网页的网址,像下面的网页包含很多电影链接

源码是这样的:

聪明的你一看就知道需要哪些信息,这个页面正文有25个电影链接,我这里用到一个list来存放这些网址,其实range(1,25)不包含25,也就是说我只存放了24个网址,原因是我的正则表达式写的不好,爬出来的第一个网址有问题,如果有兴趣可以研究下怎么完善。

需要一提的是这个正则表达式用到了两处.*?,所以匹配到的reslist是二维的。

三、changepage

  1. #changepage用来产生不同页数的链接
  2. def changepage(url,total_page):
  3. page_group = ['https://www.dygod.net/html/gndy/jddy/index.html']
  4. for i in range(2,total_page+1):
  5. link = re.sub('jddy/index','jddy/index_'+str(i),url,re.S)
  6. page_group.append(link)
  7. return page_group

这里也比较简单,点击下一页,抬头看看网址栏的网址是什么,这里是index/index_2/index_3...很容易拼接

四、main

  1. if __name__ == "__main__" :
  2. html = "https://www.dygod.net/html/gndy/jddy/index.html"
  3. print('你即将爬取的网站是:https://www.dygod.net/html/gndy/jddy/index.html')
  4. pages = input('请输入需要爬取的页数:')
  5. p1 = changepage(html,int(pages))
  6. with open ('电影天堂下载地址.lst','w') as f :
  7. j = 0
  8. for p1i in p1 :
  9. j = j + 1
  10. print('正在爬取第%d页,网址是 %s ...'%(j,p1i))
  11. p2 = pagelink(p1i)
  12. for p2i in p2 :
  13. p3 = getdownurl(p2i)
  14. if len(p3) == 0 :
  15. pass
  16. else :
  17. finalurl = p3
  18. f.write(finalurl + '\n')
  19. print('所有页面地址爬取完毕!')

main里面几乎没什么好说的,反正就是循环读取,再往文件里写进行了。

五、运行及结果

然后迅雷就可以直接导入了。(后缀为downlist或lst迅雷可以直接导入)

后记:有些可能会觉得这样一股脑的把电影都下载下来,可能有些电影太烂,下载下来就是浪费时间和资源,而手工筛选又太费事,后续会通过数据库的方式来存储影片的信息,从而筛选出需要的地址。

python爬虫--爬取某网站电影下载地址的更多相关文章

  1. python爬虫--爬取某网站电影信息并写入mysql数据库

    书接上文,前文最后提到将爬取的电影信息写入数据库,以方便查看,今天就具体实现. 首先还是上代码: # -*- coding:utf-8 -*- import requests import re im ...

  2. 使用Python爬虫爬取网络美女图片

    代码地址如下:http://www.demodashi.com/demo/13500.html 准备工作 安装python3.6 略 安装requests库(用于请求静态页面) pip install ...

  3. 用Python爬虫爬取广州大学教务系统的成绩(内网访问)

    用Python爬虫爬取广州大学教务系统的成绩(内网访问) 在进行爬取前,首先要了解: 1.什么是CSS选择器? 每一条css样式定义由两部分组成,形式如下: [code] 选择器{样式} [/code ...

  4. Python爬虫|爬取喜马拉雅音频

    "GOOD Python爬虫|爬取喜马拉雅音频 喜马拉雅是知名的专业的音频分享平台,用户规模突破4.8亿,汇集了有声小说,有声读物,儿童睡前故事,相声小品等数亿条音频,成为国内发展最快.规模 ...

  5. Python爬虫爬取全书网小说,程序源码+程序详细分析

    Python爬虫爬取全书网小说教程 第一步:打开谷歌浏览器,搜索全书网,然后再点击你想下载的小说,进入图一页面后点击F12选择Network,如果没有内容按F5刷新一下 点击Network之后出现如下 ...

  6. python爬虫—爬取英文名以及正则表达式的介绍

    python爬虫—爬取英文名以及正则表达式的介绍 爬取英文名: 一.  爬虫模块详细设计 (1)整体思路 对于本次爬取英文名数据的爬虫实现,我的思路是先将A-Z所有英文名的连接爬取出来,保存在一个cs ...

  7. Python爬虫 - 爬取百度html代码前200行

    Python爬虫 - 爬取百度html代码前200行 - 改进版,  增加了对字符串的.strip()处理 源代码如下: # 改进版, 增加了 .strip()方法的使用 # coding=utf-8 ...

  8. python爬虫爬取内容中,-xa0,-u3000的含义

    python爬虫爬取内容中,-xa0,-u3000的含义 - CSDN博客 https://blog.csdn.net/aiwuzhi12/article/details/54866310

  9. 一个简单的python爬虫,爬取知乎

    一个简单的python爬虫,爬取知乎 主要实现 爬取一个收藏夹 里 所有问题答案下的 图片 文字信息暂未收录,可自行实现,比图片更简单 具体代码里有详细注释,请自行阅读 项目源码: # -*- cod ...

随机推荐

  1. BZOJ 1770: [Usaco2009 Nov]lights 燈 [高斯消元XOR 搜索]

    题意: 经典灯问题,求最少次数 本题数据不水,必须要暴搜自由元的取值啦 想了好久 然而我看到网上的程序都没有用记录now的做法,那样做遇到自由元应该可能会丢解吧...? 我的做法是把自由元保存下来,枚 ...

  2. POJ1269 Intersecting Lines[线段相交 交点]

    Intersecting Lines Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 15145   Accepted: 66 ...

  3. pandas中的分组技术

    目录 1  分组操作 1.1  按照列进行分组 1.2  按照字典进行分组 1.3  根据函数进行分组 1.4  按照list组合 1.5  按照索引级别进行分组 2  分组运算 2.1  agg 2 ...

  4. OpenCV角点检测goodFeaturesToTrack()源代码分析

    上面一篇博客分析了HARRIS和ShiTomasi角点检测的源代码.而为了提取更准确的角点,OpenCV中提供了goodFeaturesToTrack()这个API函数,来获取更加准确的角点位置.这篇 ...

  5. 通过读取配置文件,启动mongodb

    在实际的项目中,经常利用mongodb数据库做缓存,mongodb的并发性比较高,所以对于快速存储.读取信息有很多优点.在项目中对于第一次的数据请求会直接访问数据库,而对于获得的信息通常都会在此时刻存 ...

  6. JMeter性能测试入门--偏重工具的使用

    1.JMeter整体简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试 ...

  7. python并发编程之线程(一):线程&守护线程&全局解释器锁

      一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.pyth ...

  8. maven指定部署的服务器类型

    <!-- 指定部署的服务器类型 --> <plugins> <!-- <plugin> <groupId>org.apache.tomcat.ma ...

  9. 百度前端技术学院js任务三

    任务地址:http://ife.baidu.com/course/detail/id/98 代码: <!DOCTYPE> <html> <head> <met ...

  10. HDU - 4496 City 逆向并查集

    思路:逆向并查集,逆向加入每一条边即可.在获取联通块数量的时候,直接判断新加入的边是否合并了两个集合,如果合并了说明联通块会减少一个,否则不变. AC代码 #include <cstdio> ...