鱼C论坛

 找回密码
 立即注册
查看: 3352|回复: 3

[技术交流] 18 自动模拟HTTP请求与百度信息自动搜索爬虫实战

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

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

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

x
本帖最后由 和vvv 于 2017-6-22 10:01 编辑
18 自动模拟HTTP请求与百度信息自动搜索爬虫实战
客户端如果要与服务器端进行通讯,需要通过http请求进行。http请求有很多种,我们主要利用get和post两种请求方式。比如登录、搜索某些信息是会用到。
简单理解,get是从服务器上获取数据,post是向服务器传送数据。


(1)接下来通过百度搜索来了解get请求。没错,搜索引擎使用的就是get方式。一般url格式是:
  1. 请求url?字段1=值&字段2=值&...
复制代码

我们在百度搜索首页搜索Python关键字。在搜索结果页面的地址栏可以发现这样的url:
  1. https://www.baidu.com/s?wd=Python&rsv_spt=1&rsv_iqid=0xe6c1eb1400105447&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=2&rsv_sug1=1&rsv_sug7=100&rsv_sug2=0&inputT=2650&rsv_sug4=37731
复制代码
要用爬虫来实现自动搜索,必须先要构造get请求的url。通过尝试,我们发现上面的url可以精简为:
  1. https://www.baidu.com/s?wd=Python
复制代码
现在规律很明显了,请求url为:
  1. https://www.baidu.com/s?wd=关键字
复制代码
尝试搜索一下:https://www.baidu.com/s?wd=百度。               成功。

于是很高兴地可以写出:
  1. import urllib.request
  2. keyword = "Python"
  3. data = urllib.request.urlopen("https://www.baidu.com/s?wd="+str(keyword)).read().decode("utf-8")
  4. print(data)
复制代码
但结果:
  1. <html>
  2. <head>
  3.         <script>
  4.                 location.replace(location.href.replace("https://","http://"));
  5.         </script>
  6. </head>
  7. <body>
  8.         <noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
  9. </body>
  10. </html>
复制代码
经分析发现,要将“https”改为“http”:
  1. import urllib.request
  2. keyword = "Python"
  3. data = urllib.request.urlopen("http://www.baidu.com/s?wd="+str(keyword)).read().decode("utf-8")
  4. print(len(data))
复制代码
  1. 319161
复制代码
只要爬取返回数据量很大时,一般是访问成功了的。


(2)接下来我们从搜索结果中提取搜索各个结果标题。
图片1.png

打开搜索结果的页面,分析源代码。“Ctrl+F”查找“Python 基础教程 | 菜鸟教程”。可以得到:
  1. data-tools='{"title":"Python 基础教程 | 菜鸟教程",
复制代码
再搜索'
data-tools='{"title":',可以发现有6个结果,且基本满足要求。因此正则表达式可以这样写:
  1. pat = '''data-tools='{"title":"(.*?)"'''
复制代码
所以:
  1. import urllib.request
  2. import re
  3. keyword = "Python"
  4. data = urllib.request.urlopen("http://www.baidu.com/s?wd="+keyword).read().decode("utf-8")
  5. print(len(data))
  6. pat = '''data-tools='{"title":"(.*?)"'''
  7. rst = re.compile(pat).findall(data)
  8. print(rst)
复制代码
结果:
  1. 298739
  2. ['Welcome to Python.org', 'Download Python | Python.org', 'Python 基础教程 | 菜鸟教程', 'Python教程 - 廖雪峰的官方网站', 'Python 简介 | 菜鸟教程', 'Python - 伯乐在线']
复制代码


到这里,就实现了爬虫实现自动搜索的功能了。

(3)但是,当我们将搜索关键词改为中文时,出现了错误:
  1. import urllib.request
  2. keyword = "人生"
  3. data = urllib.request.urlopen("http://www.baidu.com/s?wd="+str(keyword)).read().decode("utf-8")
  4. print(len(data))
复制代码
报错,列举关键的一条:
  1. UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-11: ordinal not in range(128)
复制代码
发现是编码的问题。因为url是不能直接识别中文的,需要转一下码。例如我们搜索“人生”,可以发现地址栏(复制出来):
  1. https://www.baidu.com/s?wd=%E4%BA%BA%E7%94%9F
复制代码
wd之后的那一串就是“人生”经过转码后的结果。可以使用quote()函数对中文进行转码。
  1. import urllib.request
  2. key = "人生"
  3. keyword = urllib.request.quote(key)
  4. data = urllib.request.urlopen("http://www.baidu.com/s?wd="+str(keyword)).read().decode("utf-8")
  5. print(len(data))
复制代码
结果:
  1. 299763
复制代码
显然是成功的。


(4)很明显,我们只打印出了第一页的内容。我们还需要实现翻页的功能。

打开搜索“Python”的页面:https://www.baidu.com/s?wd=Python,点击下一页,观察地址栏的变化:
  1. https://www.baidu.com/s?wd=Python&pn=10&oq=Python&ie=utf-8&usm=5&rsv_pq=b8e461bc001358bd&rsv_t=1552vBDrByizyqVppOh%2BCPW3pRJLFithNXyngIhfwp%2FIDw77IAtjRV%2FDMWk
复制代码
尝试将其精简一下:
  1. https://www.baidu.com/s?wd=Python&pn=10
复制代码
可以发现,这个链接是可以访问成功的,并且是第二页。
再点下一页,观察地址栏:
  1. https://www.baidu.com/s?wd=Python&pn=20&oq=Python&ie=utf-8&rsv_pq=dfac4aa5000e4c88&rsv_t=3e178Yh7y8k4flLh1FdPRSVoEF6ib91gzzNPPSogUoKPZz2d5lN0ipTV9VU
复制代码
精简之后(这是第三页):
  1. https://www.baidu.com/s?wd=Python&pn=20
复制代码

于是,我们可以总结出翻页的规律:
  1. https://www.baidu.com/s?wd=关键词&pn=(页数-1)*10
复制代码
访问一下这个链接(第5页):
https://www.baidu.com/s?wd=Python&pn=40。是可以访问成功的,并且是第 5页。

于是,爬虫就可以写了:
  1. import urllib.request
  2. import re
  3. keyword = "Python"
  4. for page in range(0,10):
  5.     data = urllib.request.urlopen("http://www.baidu.com/s?wd="+keyword+"&pn="+str(page*10)).read().decode("utf-8")
  6.     print(len(data))
  7.     pat = '''data-tools='{"title":"(.*?)"'''
  8.     rst = re.compile(pat).findall(data)
  9.     print(rst)
复制代码
结果:
  1. import urllib.request
  2. import re
  3. keyword = "Python"
  4. for page in range(0,10):
  5.     data = urllib.request.urlopen("http://www.baidu.com/s?wd="+keyword+"&pn="+str(page*10)).read().decode("utf-8")
  6.     print(len(data))
  7.     pat = '''data-tools='{"title":"(.*?)"'''
  8.     rst = re.compile(pat).findall(data)
  9.     print(rst)
复制代码
结果:
  1. 178867
  2. ['Welcome to Python.org', 'Download Python | Python.org', 'Python 基础教程 | 菜鸟教程', 'Python教程 - 廖雪峰的官方网站', 'Python 简介 | 菜鸟教程', '玩蛇网 - Python教程学习与Python资源分享平台']
  3. 278041
  4. ['可以用 Python 编程语言做哪些神奇好玩的事情? - 知乎', 'Python开源软件 - 开源中国社区', 'Download Python | Python.org', 'PythonTab:Python中文开发者社区门户', '快速入门:十分钟学会Python - 文章 - 伯乐在线', 'Python中国', 'python-脚本之家', 'Python (programming language) - Wikipedia', 'python documentation', 'Python Release Python 3.5.0 | Python.org']
  5. 292421
  6. ['Python|Python 3.5.2(Python下载)官方版-绿色下载吧', 'ActivePython | ActiveState', 'Python3 教程 | 菜鸟教程', 'PyPI - the Python Package Index : Python Package Index', 'Python - 文章 - 伯乐在线', 'IBM developerWorks 中国 : Python 技术专题', 'Index of /python/', 'MySQL :: Download Connector/Python', '标签Python - 第1页 -- 现代魔法学院', 'Newest \\'python\\' Questions - Stack Overflow']
  7. 287201
  8. ['千锋Python学院-中国Python培训|Python开发培训|Python培训课程...', 'python starship', '专题:Python实用开发指南_51CTO.COM - 技术成就梦想 - 中国领先的...', 'wxPython', '全部Python课程 - CSDN学院 - CSDN', 'Pythoner | 你像从前一样的Python学习笔记', 'Python部落 ', 'Python SDK - 七牛开发者中心', 'MicroPython - Python for microcontrollers', 'python培训 北京金源万博打造PYTHON培训行业第一品牌!']
  9. 280890
  10. ['另外参考spark的python api', 'python基础教程_python高级教程_python手册_python实例 - 红黑联盟', 'python培训相关的python 教程,下载和主机都可以找老王python', 'gensim: Topic modelling for humans', 'Visualize Python, Java, JavaScript, TypeScript, and Ruby code...', 'Planet Python', 'python实例来源', '中蟒(中文 Python) 編程語言網站 chinesepython', 'Python Excel', 'Learn Python the Hard Way']
  11. 280131
  12. ['Learn Python the Hard Way', 'The Python Challenge', 'Python2orPython3 - Python Wiki', 'Python4cn(news, jobs)', 'xkcd: Python', 'Python Quick Guide', 'python 基础语法之一 - Legend的博客 - 博客频道 - CSDN.NET', 'Python MongoDB Drivers', 'Getting Started on Heroku with Python | Heroku Dev Center', 'WinPython']
  13. 279715
  14. ['python-requests', '为什么有那么多人选择Python?_百度文库', 'Python开发【第二篇】:初识Python - 望展 - 博客园', 'Paho - Open Source messaging for M2M ', 'Python是什么?Python如何使用?- Python教程-PHP中文网', 'IronPython.net / ', '在线手册中心 - 最全的在线手册文档 - Python手册|Flask手册|...', 'PyThon - 收藏夹 - 知乎', 'Python_1-布布扣-bubuko.com ', 'Host, run, and code Python in the cloud: PythonAnywhere']
  15. 297556
  16. ['mod_python - Apache / Python Integration', 'The Mouse Vs. The Python | Python Programming from the ...', 'Python教程:什么是Python - 浙西文库', '马哥教育官网-专业Linux培训|Python培训 | 排名领先的泛Linux运维...', 'Python入门_Python入门教程_python入门视频教程-慕课网 ', 'invent your own computer games with python', 'Python Extension Packages for Windows - Christoph Gohlke', 'Python Data Analysis Library — pandas: Python Data Analysis ...', 'Matplotlib: Python plotting — Matplotlib 2.0.2 documentation', 'scientific python stack']
  17. 292283
  18. ['一个从事Python多年开发的自述', 'python-requests', 'IronPython - Download: 2.7.5', 'Python 开发已成趋势:几种主流的Python开发板对比 - m15169680878...', 'python - 爱线下首页-专注于零售业,提供线上线下整合营销、云Wi-...', '目前比较好的python ide有pycharm', 'python-dateutil - Labix', 'python nltk', 'w3school 在线教程', '<3> python scrapy']
  19. 286943
  20. ['>> python unicode strings', 'Python确实比较慢,但我不在乎,翻译 我不在乎 - 科技 - 飞翔资讯网', '...服务器responseBodystartResponseresponseHeaderstat_Python的...', '[译] 3 个开源的 Python Shell - 头条精选 - 开发者头条', '八爪鱼采集器 - 最好用的网页数据采集器 ', 'PHPERZ 聚焦互联网', '拉勾网-最专业的互联网招聘平台_找工作_招聘_人才网_求职', '巨蟒与圣杯 Monty Python and the Holy Grail(1975)', 'RBTools Documentation | Documentation | Review Board', 'PyPI - the Python Package Index : Python Package Index']
复制代码

很明显,已经成功了。




评分

参与人数 1鱼币 +12 收起 理由
小甲鱼 + 12 支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2017-9-27 20:07:20 | 显示全部楼层
请问下这个正则表达式是看哪个标签下出来的 ,能不能详细点 ,感谢。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-3 09:59:35 From FishC Mobile | 显示全部楼层
你的地址栏是如何进行精简的,后面的不是有很大区别么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-3 10:06:33 | 显示全部楼层
幽梦三影 发表于 2018-7-3 09:59
你的地址栏是如何进行精简的,后面的不是有很大区别么

地址栏后面的其实是广告啦,“?wd=关键字”后面的都可以去掉的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-27 04:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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