使用 Python 爬取网页数据

本文作者:IMWeb HuQingyang 原文出处:IMWeb社区 未经同意,禁止转载

在需要过去一些网页上的信息的时候,使用 Python 写爬虫来爬取十分方便。

1. 使用 urllib.request 获取网页

urllib 是 Python 內建的 HTTP 库, 使用 urllib 可以只需要很简单的步骤就能高效采集数据; 配合 Beautiful 等 HTML 解析库, 可以编写出用于采集网络数据的大型爬虫;

注: 示例代码使用Python3编写; urllib 是 Python2 中 urllib 和 urllib2 两个库合并而来, Python2 中的 urllib2 对应 Python3中的 urllib.request

简单的示例:

import urllib.request                    # 引入urllib.request

response =  urllib.request.urlopen('http://www.zhihu.com')            # 打开URL
html = response.read()            # 读取内容
html = html.decode('utf-8')            # 解码
print(html)

2. 伪造请求头信息

有时爬虫发起的请求会被服务器拒绝, 这时就需要将爬虫伪装成人类用户的浏览器, 这通常通过伪造请求头信息实现, 如:

import urllib.request

head = {}
head['User-Agent']='Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0..'

req = urllib.request.Request(url,head)            # 伪造请求头
response = urllib.request.urlopen(req)
html = response.read().decode('utf-8')
print(html)

3. 伪造请求主体

在爬取某一些网站时, 需要向服务器 POST 数据, 这时就需要伪造请求主体;

为了实现有道词典在线翻译脚本, 在 Chrome 中打开开发工具, 在 Network 下找到方法为 POST 的请求, 观察数据可以发现请求主体中的 ‘ i ‘ 为经过 URL 编码的需要翻译的内容, 因此可以伪造请求主体, 如:

import urllib.request
import urllib.parse
import json

while True:
    content = input('请输入要翻译的内容:')
    if content == 'exit!':
        break

    url='http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null'

    # 请求主体
    data = {}
    data['type'] = "AUTO"
    data['i'] = content
    data['doctype'] = "json"
    data['xmlVersion'] = "1.8"
    data['keyfrom'] = "fanyi.web"
    data['ue'] = "UTF-8"
    data['action'] = "FY_BY_CLICKBUTTON"
    data['typoResult'] = "true"
    data = urllib.parse.urlencode(data).encode('utf-8')

    head = {}
    head['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0'

    req = urllib.request.Request(url,data,head)            # 伪造请求头和请求主体
    response = urllib.request.urlopen(req)
    html = response.read().decode('utf-8')

    target = json.loads(html)
    print('翻译结果: ',(target['translateResult'][0][0]['tgt']))

也可以使用 add_header() 方法伪造请求头, 如:

import urllib.request
import urllib.parse
import json

while True:
  content = input('请输入要翻译的内容(exit!):')
  if content == 'exit!':
        break

    url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null'

    # 请求主体
    data = {}
  data['type'] = "AUTO"
  data['i'] = content
  data['doctype'] = "json"
  data['xmlVersion'] = "1.8"
  data['keyfrom'] = "fanyi.web"
  data['ue'] = "UTF-8"
  data['action'] = "FY_BY_CLICKBUTTON"
  data['typoResult'] = "true"
  data = urllib.parse.urlencode(data).encode('utf-8')

  req = urllib.request.Request(url,data)
  req.add_header('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0')

  response = urllib.request.urlopen(req)
  html=response.read().decode('utf-8')

  target = json.loads(html)
  print('翻译结果: ',(target['translateResult'][0][0]['tgt']))

4. 使用代理IP

为了避免爬虫采集过于频繁导致的IP被封的问题, 可以使用代理IP, 如:

# 参数是一个字典{'类型':'代理ip:端口号'}
proxy_support = urllib.request.ProxyHandler({'type': 'ip:port'})

# 定制一个opener
opener = urllib.request.build_opener(proxy_support)

# 安装opener
urllib.request.install_opener(opener)

#调用opener
opener.open(url)

注: 使用爬虫过于频繁的访问目标站点会占用服务器大量资源, 大规模分布式爬虫集中爬取某一站点甚至相当于对该站点发起DDOS攻击; 因此, 使用爬虫爬取数据时应该合理安排爬取频率和时间; 如: 在服务器相对空闲的时间 ( 如: 凌晨 ) 进行爬取, 完成一次爬取任务后暂停一段时间等;

5. 检测网页的编码方式

尽管大多数网页都是用 UTF-8 编码, 但有时候会遇到使用其他编码方式的网页, 因此必须知道网页的编码方式才能正确的对爬取的页面进行解码;

chardet 是 python 的一个第三方模块, 使用 chardet 可以自动检测网页的编码方式;

安装 chardet : pip install charest

使用:

import chardet
url = 'http://www,baidu.com'
html = urllib.request.urlopen(url).read()

>>> chardet.detect(html)
{'confidence': 0.99, 'encoding': 'utf-8'}

6. 获得跳转链接

有时网页一个页面需要在原始 URL 的基础上进行一次甚至多次跳转才能最终到达目的页面, 因此需要正确的处理跳转;

通过 requests 模块的 head() 函数获得跳转链接的 URL , 如

url='https://unsplash.com/photos/B1amIgaNkwA/download/'
res = requests.head(url)
re=res.headers['Location']

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏彭湖湾的编程世界

来,我们手写一个简易版的mock.js吧(模拟fetch && Ajax请求)

比较符合我们使用习惯的,也许是下面这种mock方式,有一个专门的配置文件,管理请求的url和返回值。每个请求对应输出数组中的一个对象,对象的rule属性可以是一...

10430
来自专栏Devops专栏

Flask 使用 request 处理GET POST请求、上传文件

在Django框架开发中,request对象就是用来处理GET\POST请求的关键对象,而Flask框架也是一样的。

10420
来自专栏技术栈

微服务API开放授权平台的设计与实现

本文所介绍的项目是一个基于oath2协议的应用,实现的的功能逻辑与QQ互联,微博开放平台类似,都是同一套认证授权流程。

12120
来自专栏从零开始学自动化测试

python测试开发django-71.自定义标签tag

django的模板里面有很多标签可以快速实现一些功能,比如{% url url_name%} 可以快捷的导入一个本地url地址。 上一篇我们可以自定义一些过滤器...

8920
来自专栏Spring Boot 2.X 系列

Spring Boot 2.X(十七):应用监控之 Spring Boot Admin 使用及配置

Spring Boot Admin 是 Spring Boot 应用程序运行状态监控和管理的后台界面。最新UI使用vue.js重写。

9220
来自专栏毛毛v5

nginx配置图片文件jpg重定向到php进行权限校验

形如/image/vip/2019/11/xxx.jpg的文件被内部重定向到/jpg.php?s=/image/vip/2019/11/xxx.jpg,php文...

7710
来自专栏志学Python

带你认识 flask 分页

让我们从简单的事情开始吧。首页需要有一个表单,用户可以在其中键入新动态。我创建一个表单类:

6420
来自专栏可能是东半球最正规的API社区

老旧话题:重新看看PHP的session

这基本上算是个老旧的话题了,几乎所有phper在第一次面试的时候都会被问到关于session的问题,如果不出意外,往往是如下三板斧:

10340
来自专栏算法channel

70道NumPy 测试题

问题:在不使用硬编码的前提下创建以下模式。仅使用 NumPy 函数和以下输入数组 a。

7210
来自专栏云爬虫技术研究笔记

面试官:你连RESTful都不知道我怎么敢要你?

看过很多RESTful相关的文章总结,参齐不齐,结合工作中的使用,非常有必要归纳一下关于RESTful架构方式了,RESTful只是一种架构方式的约束,给出一种...

11020

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励