鱼C论坛

 找回密码
 立即注册
查看: 5175|回复: 27

[技术交流] 22 Python新闻爬虫实战

[复制链接]
发表于 2017-6-23 15:22:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 和vvv 于 2017-6-27 09:56 编辑
22 Python新闻爬虫实战

一、新闻爬虫需求及实现思路

需求:将腾讯新闻首页所有新闻都爬到本地

思路:先爬首页,通过正则获取新闻链接。然后依次爬各新闻,并存储到本地。

二、新闻爬虫编写

(1)首先利用urllib库尝试爬取,看是否存在爬取限制。
  1. import urllib.request
  2. import re

  3. url = "http://news.qq.com/"
  4. data = urllib.request.urlopen(url).read().decode('utf-8')
  5. print(len(data))
复制代码
结果出现了错误:
  1. ---------------------------------------------------------------------------
  2. UnicodeDecodeError                        Traceback (most recent call last)
  3. <ipython-input-5-884fd8f1ecfe> in <module>()
  4.       3
  5.       4 url = "http://news.qq.com/"
  6. ----> 5 data = urllib.request.urlopen(url).read().decode('utf-8')
  7.       6 print(len(data))

  8. UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
复制代码
显然这是编码的问题,但我们用浏览器打开腾讯新闻首页,查看源代码发现其编码就是utf-8。把它改成GBK之后,有时能成功,但大多数情况下都没有成功。
  1. ---------------------------------------------------------------------------
  2. UnicodeDecodeError                        Traceback (most recent call last)
  3. <ipython-input-14-1048877e7349> in <module>()
  4.       3
  5.       4 url = "http://news.qq.com/"
  6. ----> 5 data = urllib.request.urlopen(url).read().decode('GBK')
  7.       6 print(len(data))

  8. UnicodeDecodeError: 'gbk' codec can't decode byte 0x8b in position 1: illegal multibyte sequence
复制代码
这是怎么回事呢?
网上找了一些资料,原来如此。这是因为在网页返回内容的这里是“gzip”。
图片1.png

这条信息代表本地可以接收压缩格式的数据,而服务器在处理时就将大文件压缩再发回客户端,浏览器在接收完成后在本地对这个文件又进行了解压操作。出错的原因是因爬虫程序没有解压这个文件。用urllib库会出现这个问题。


这个问题,终于解决了:
  1. #使用gzip包来进行解压
  2. import urllib.request
  3. import gzip
  4. import chardet

  5. url = 'http://news.qq.com/'
  6. response = gzip.decompress(urllib.request.urlopen(url).read())
  7. print(chardet.detect(response))
复制代码
结果:
  1. {'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
复制代码
访问成功了就可以进行其他的操作了。


在这里,我采用的是另一种方法:使用requests库代替urllib库获取网页内容。
  1. import requests
  2. url = "http://news.qq.com/"
  3. data = requests.get(url).text
  4. print(len(data))
复制代码
  1. 326571
复制代码
结果没有问题。

(2)分析网页源码,找出新闻链接的规律,写出正则表达式,最后是实现

用搜狗浏览器(其他也行)打开腾讯新闻首页,右键“查看源文件”。随便复制一条新闻的标题,然后再源码中查找。寻找用正则表达式比较好提取的链接:
  1. <a target="_blank" class="linkto" >于欢案二审宣判:原判量刑过重 无期改判5年</a>
复制代码
或者

  1.             <li><span>5</span><a  target="_blank">于欢案二审宣判:原判量刑过重 无期改判5年</a></li>
复制代码
然后再搜索‘<a target="_blank" class="linkto"’,可以发现有50多条。搜索‘<li><span>’,只有10多条。显然提取新闻链接正则表达式可以这样提取。
  1. pat = '<div class="text">.*?<a target="_blank" class="linkto" href="(.*?)"'
复制代码
说明一点,正则表达式尽量从网页标签的外围开始提取。
实践一下:
  1. import requests
  2. import re
  3. url = "http://news.qq.com/"
  4. data = requests.get(url).text
  5. print(len(data))
  6. pat = '<div class="text">.*?<a target="_blank" class="linkto" href="(.*?)"'
  7. #模式修正符让 . 能够匹配换行
  8. allurl = re.compile(pat,re.S).findall(data)
  9. for i in allurl:
  10.     print(i)
复制代码
显然成功了。
  1. 326570
  2. http://news.qq.com/a/20170623/011044.htm
  3. http://digi.tech.qq.com/a/20170623/022898.htm
  4. http://news.qq.com/a/20160418/023091.htm
  5. http://news.qq.com/a/20170623/015424.htm
  6. http://tech.qq.com/a/20170623/020852.htm
  7. http://tech.qq.com/a/20170623/024206.htm
  8. http://stock.qq.com/a/20170623/018153.htm
  9. http://tech.qq.com/a/20170623/009320.htm
  10. http://news.qq.com/a/20170623/020843.htm
  11. http://news.qq.com/a/20170623/020322.htm
  12. http://news.qq.com/a/20170623/008309.htm
  13. http://news.qq.com/a/20170623/015176.htm
  14. http://news.qq.com/a/20170623/004635.htm
  15. http://news.qq.com/a/20170623/001194.htm
  16. http://news.qq.com/a/20170623/001047.htm
  17. http://news.qq.com/a/20170623/002015.htm
  18. http://news.qq.com/a/20170623/001868.htm
  19. http://news.qq.com/a/20170623/001891.htm
  20. http://news.qq.com/a/20170623/001954.htm
  21. http://news.qq.com/a/20170623/001391.htm
  22. http://tech.qq.com/a/20170622/057876.htm
  23. http://news.qq.com/a/20170623/001224.htm
  24. http://news.qq.com/a/20170623/001299.htm
  25. http://news.qq.com/a/20170622/052991.htm
  26. http://news.qq.com/a/20170623/001274.htm
  27. http://news.qq.com/a/20170622/053439.htm
  28. http://news.qq.com/a/20170622/046523.htm
  29. http://finance.qq.com/a/20170622/053428.htm
  30. http://news.qq.com/a/20170622/052374.htm
  31. http://news.qq.com/a/20170622/042882.htm
  32. http://tech.qq.com/a/20170622/043507.htm
  33. http://sports.qq.com/a/20170622/047401.htm
  34. http://sports.qq.com/a/20170622/041502.htm
  35. http://news.qq.com/a/20170622/038445.htm
  36. http://ent.qq.com/a/20170622/020317.htm
  37. http://tech.qq.com/a/20170622/039913.htm
  38. http://news.qq.com/a/20170622/043382.htm
  39. http://news.qq.com/a/20170622/040303.htm
  40. http://edu.qq.com/a/20170622/040148.htm
  41. http://news.qq.com/a/20170622/026520.htm
  42. http://news.qq.com/a/20170622/034117.htm
复制代码


既然有了新闻链接,我们是不是还应该有新闻名呢。可以这样来:
  1. import requests
  2. import re
  3. url = "http://news.qq.com/"
  4. data = requests.get(url).text
  5. print(len(data))
  6. pat = '<div class="text">.*?<a target="_blank" class="linkto" href=".*?">(.*?)</a>'
  7. #模式修正符让 . 能够匹配换行
  8. allurl = re.compile(pat,re.S).findall(data)
  9. for i in allurl:
  10.     print(i)
复制代码
  1. 326570
  2. 于欢案二审宣判:原判量刑过重 无期改判5年
  3. 苹果发布官方声明:去年下半年开始已移除10万app
  4. 巴西众院弹劾总统案获通过 罗塞夫政党承认落败
  5. 美媒:美国男子被控向中国传递绝密文件 或被判死刑
  6. 乐视还债表现不佳 仁宝电脑暂停向乐视致新入股7亿元
  7. LinkedIn中国总裁沈博阳离职 曾志恒任代理中国总裁
  8. 创6个月新高 !万科A大涨近9% 分析称深铁入主是利好
  9. 董明珠谈上手机开机画面:不是因为我美
  10. 人社部:养老保险基金在东北出现当期收不抵支
  11. 河北发布雄安新区交通规划:将以轨道交通为主
  12. “中国史”不属于历史学专业?女生报考公务员被拒
  13. 崔顺实首罪宣判:因涉嫌妨碍业务等罪获刑3年
  14. 篮球场暂时关闭,洛阳广场舞大爷大妈占领羽毛球场
  15. 深圳一房企被爆欠薪3000万 房企“钱荒”来临?
  16. 实地探访“巴铁”投资方 投资者三句不离“兑付”
  17. 特朗普建议把美墨边境墙修成太阳能墙:越高价值越大
  18. 泰国国王在德国遭两名少年用橡皮子弹射击 未被击中
  19. 军队武警部队停止有偿服务如何做补偿?官方回应
  20. 日媒:安倍ZF拟修改和平宪法,将自卫队地位明文化
  21. 北约战机威胁俄防长座机被驱离 俄官员:下流行为
  22. 特斯拉独家回应:正与上海市ZF讨论建厂可能性
  23. 深山丛林暗藏制毒窝点 警方在悬崖上开辟抓捕通道
  24. 万达复星遭“股债双杀” 是监管进深水区结的果?
  25. 俄外交部:IS头目巴格达迪“很可能已经被消灭”
  26. 校园贷诈骗案数据:大学生从受骗者变施骗者
  27. 文在寅:萨德部署“神秘”加速 已有2架发射台部署
  28. 巴拿马总统明确称两岸“外交休兵”已结束 中方回应
  29. 遭遇股价狂跌 复星仍忙着在俄罗斯买地产和黄金项目
  30. 危地马拉沿岸近海发生6.8级地震 震源深度40千米
  31. 杭州豪宅大火母子4人遇难 34岁保姆有重大作案嫌疑
  32. 乐视拖欠中移动费用 290G带宽或被下线
  33. 国乒意外频出士气低迷 王楠老公曝全队已被禁声
  34. 足协重磅罚单:奥斯卡停赛八场罚4万 上港被罚9万
  35. 女硕士笔试面试第一被徐州人社局拒录 官方回应
  36. “中国好老板”又上线!黄晓明给员工放假躲雨
  37. 滴滴回应作家六六:动态调价加价费用100%归司机
  38. 阿富汗一银行遭炸药车袭击29人死亡 当时多人正取钱
  39. 韩国防部:朝外交官“暂停核试”言论不值一评
  40. 北京重庆等12地高考分数线公布,湖北等多地今日发布
  41. 土壤污染防治法草案:污染地块不得作为住宅用地
  42. 中国学生在美跳海身亡 死者父亲将赴美处理后事
复制代码

把他们组合起来:
游客,如果您要查看本帖隐藏内容请回复


结果:
  1. 于欢案二审宣判:原判量刑过重 无期改判5年
  2. http://news.qq.com/a/20170623/011044.htm
  3. 苹果发布官方声明:去年下半年开始已移除10万app
  4. http://digi.tech.qq.com/a/20170623/022898.htm
  5. 巴西众院弹劾总统案获通过 罗塞夫政党承认落败
  6. http://news.qq.com/a/20160418/023091.htm
  7. 美媒:美国男子被控向中国传递绝密文件 或被判死刑
  8. http://news.qq.com/a/20170623/015424.htm
  9. 乐视还债表现不佳 仁宝电脑暂停向乐视致新入股7亿元
  10. http://tech.qq.com/a/20170623/020852.htm
  11. LinkedIn中国总裁沈博阳离职 曾志恒任代理中国总裁
  12. http://tech.qq.com/a/20170623/024206.htm
  13. 创6个月新高 !万科A大涨近9% 分析称深铁入主是利好
  14. http://stock.qq.com/a/20170623/018153.htm
  15. 董明珠谈上手机开机画面:不是因为我美
  16. http://tech.qq.com/a/20170623/009320.htm
  17. 人社部:养老保险基金在东北出现当期收不抵支
  18. http://news.qq.com/a/20170623/020843.htm
  19. 河北发布雄安新区交通规划:将以轨道交通为主
  20. http://news.qq.com/a/20170623/020322.htm
  21. “中国史”不属于历史学专业?女生报考公务员被拒
  22. http://news.qq.com/a/20170623/008309.htm
  23. 崔顺实首罪宣判:因涉嫌妨碍业务等罪获刑3年
  24. http://news.qq.com/a/20170623/015176.htm
  25. 篮球场暂时关闭,洛阳广场舞大爷大妈占领羽毛球场
  26. http://news.qq.com/a/20170623/004635.htm
  27. 深圳一房企被爆欠薪3000万 房企“钱荒”来临?
  28. http://news.qq.com/a/20170623/001194.htm
  29. 实地探访“巴铁”投资方 投资者三句不离“兑付”
  30. http://news.qq.com/a/20170623/001047.htm
  31. 特朗普建议把美墨边境墙修成太阳能墙:越高价值越大
  32. http://news.qq.com/a/20170623/002015.htm
  33. 泰国国王在德国遭两名少年用橡皮子弹射击 未被击中
  34. http://news.qq.com/a/20170623/001868.htm
  35. 军队武警部队停止有偿服务如何做补偿?官方回应
  36. http://news.qq.com/a/20170623/001891.htm
  37. 日媒:安倍ZF拟修改和平宪法,将自卫队地位明文化
  38. http://news.qq.com/a/20170623/001954.htm
  39. 北约战机威胁俄防长座机被驱离 俄官员:下流行为
  40. http://news.qq.com/a/20170623/001391.htm
  41. 特斯拉独家回应:正与上海市ZF讨论建厂可能性
  42. http://tech.qq.com/a/20170622/057876.htm
  43. 深山丛林暗藏制毒窝点 警方在悬崖上开辟抓捕通道
  44. http://news.qq.com/a/20170623/001224.htm
  45. 万达复星遭“股债双杀” 是监管进深水区结的果?
  46. http://news.qq.com/a/20170623/001299.htm
  47. 俄外交部:IS头目巴格达迪“很可能已经被消灭”
  48. http://news.qq.com/a/20170622/052991.htm
  49. 校园贷诈骗案数据:大学生从受骗者变施骗者
  50. http://news.qq.com/a/20170623/001274.htm
  51. 文在寅:萨德部署“神秘”加速 已有2架发射台部署
  52. http://news.qq.com/a/20170622/053439.htm
  53. 巴拿马总统明确称两岸“外交休兵”已结束 中方回应
  54. http://news.qq.com/a/20170622/046523.htm
  55. 遭遇股价狂跌 复星仍忙着在俄罗斯买地产和黄金项目
  56. http://finance.qq.com/a/20170622/053428.htm
  57. 危地马拉沿岸近海发生6.8级地震 震源深度40千米
  58. http://news.qq.com/a/20170622/052374.htm
  59. 杭州豪宅大火母子4人遇难 34岁保姆有重大作案嫌疑
  60. http://news.qq.com/a/20170622/042882.htm
  61. 乐视拖欠中移动费用 290G带宽或被下线
  62. http://tech.qq.com/a/20170622/043507.htm
  63. 国乒意外频出士气低迷 王楠老公曝全队已被禁声
  64. http://sports.qq.com/a/20170622/047401.htm
  65. 足协重磅罚单:奥斯卡停赛八场罚4万 上港被罚9万
  66. http://sports.qq.com/a/20170622/041502.htm
  67. 女硕士笔试面试第一被徐州人社局拒录 官方回应
  68. http://news.qq.com/a/20170622/038445.htm
  69. “中国好老板”又上线!黄晓明给员工放假躲雨
  70. http://ent.qq.com/a/20170622/020317.htm
  71. 滴滴回应作家六六:动态调价加价费用100%归司机
  72. http://tech.qq.com/a/20170622/039913.htm
  73. 阿富汗一银行遭炸药车袭击29人死亡 当时多人正取钱
  74. http://news.qq.com/a/20170622/043382.htm
  75. 韩国防部:朝外交官“暂停核试”言论不值一评
  76. http://news.qq.com/a/20170622/040303.htm
  77. 北京重庆等12地高考分数线公布,湖北等多地今日发布
  78. http://edu.qq.com/a/20170622/040148.htm
  79. 土壤污染防治法草案:污染地块不得作为住宅用地
  80. http://news.qq.com/a/20170622/026520.htm
  81. 中国学生在美跳海身亡 死者父亲将赴美处理后事
  82. http://news.qq.com/a/20170622/034117.htm
复制代码

(3)保存到本地

使用urllib.request.urlretrieve即可。首先要在对应目录下存在文件夹。

三、完整代码实现
  1. [hide]import requests
  2. import re
  3. import urllib.request
  4. url = "http://news.qq.com/"
  5. requests.get(url).encodeing = "utf-8"
  6. data = requests.get(url).text
  7. #print(len(data))
  8. pat = '<div class="text">.*?<a target="_blank" class="linkto" href="(.*?)"'
  9. pat1 = '<div class="text">.*?<a target="_blank" class="linkto" href=".*?">(.*?)</a>'
  10. allurl = re.compile(pat,re.S).findall(data)
  11. alltitle = re.compile(pat1,re.S).findall(data)
  12. for i in range(0,len(alltitle)):
  13.     print(alltitle[i]+"\n"+allurl[i])
  14.     urllib.request.urlretrieve(allurl[i],"f:/news/"+alltitle[i]+'.html')[/hide]
复制代码
结果,可以在相应的文件夹看到:
图片2.png

在这个项目的实现过程中,正则表达式的不同,会导致结果的不同,但主要思想是相同的:先爬取网页,用正则表达式提取出新闻链接和标题,在存储到本地。







评分

参与人数 2荣誉 +2 鱼币 +11 贡献 +2 收起 理由
流月飞星 + 2 + 3 + 2
小甲鱼 + 8 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-23 15:45:47 | 显示全部楼层
这么好的帖子竟然没人
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-15 20:20:48 | 显示全部楼层
支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-17 07:55:36 | 显示全部楼层
非常好,我学习去了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-19 18:25:50 | 显示全部楼层
111111212
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-27 10:53:51 | 显示全部楼层
感谢老铁
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-28 16:09:24 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-10-11 17:14:54 | 显示全部楼层
666666666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-10-12 09:52:39 | 显示全部楼层

学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-1 20:56:17 | 显示全部楼层
很不错,怎么控制获得的数量呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-2 21:42:31 | 显示全部楼层
学习!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-11-5 10:56:48 | 显示全部楼层
感谢分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-5 11:10:10 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-11-22 22:54:21 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-23 16:37:14 | 显示全部楼层
谢谢分享zsbd
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-24 20:10:23 | 显示全部楼层
看看,感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-27 21:26:43 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-1-25 17:17:24 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-1-25 17:50:40 | 显示全部楼层
看看,感谢看看,感谢看看,感谢看看,感谢看看,感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-1-26 05:28:10 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 07:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表