爬虫-静态网页抓取

目录


前言

        在网站设计中,纯粹的HTML格式的网页通常被称为静态网页,其数据都呈现在网页的HTML代码当中,是公开的,因此比较容易获取。在静态网页的抓取任务当中,Requests库能够有效的发送HTTP请求,并获取相应内容。下面先介绍基础内容,然后以获取豆瓣电影TOP250(网页地址为:https://movie.douban.com/top250)的所有电影的名称为例,介绍静态网页的抓取。


一、Requests库安装

pip install requests

二、发送HTTP请求

        首先,我们利用Requests库来获取某一个静态页面的内容。利用requests模块的get()方法,并传递参数URL(即需要获取的页面内容的网址),可以得到一个Response对象 r 。

import requests

# 访问CSDN主页
r = requests.get('https://www.csdn.net/')

print("文本编码:", r.encoding)
print("响应状态码:", r.status_code)
print("字符串方式的响应体:", r.text)

通过Response对象,我们可以得到服务器的相应内容。如下所示,加粗为个人常用的:

  • r.text:获取服务器相应的内容。
  • r.encoding:获取服务器内容使用的文本编码。
  • r.status_code:检测响应的状态码。返回200,表示请求成功。返回4xx,表示客户端错误。返回5xx,表示服务器错误响应。
  • r.json:Requests 中内置的 JSON 解码器。
  • r.content:以字节的方式访问请求响应体。

三、定制Requests

       对于有些网页,需要对Requests的参数进行设置才能够获取需要的数据,这包括传递URL参数、定制请求头、发送POST请求、设置超时等等。   

1 传递URL参数

        有时相位URL的查询字符串传递某种数据,如果是自己构建URL,那么数据一般会根在一个问号的后面,并且以键/值对的形式置于 URL 中。例如, http://httpbin.org/get?key1=val1。
        Requests 允许你使用 params 关键字参数,以一个字符串字典来提供这些参数。

payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)
print("URL正确编码:",r.url)
# http://httpbin.org/get?key1=value1&key2=value2

还可以将一个列表作为值传入:

payload = {'key1': 'value1', 'key2': ['value2', 'value3']}

r = requests.get('http://httpbin.org/get', params=payload)
print(r.url)
# http://httpbin.org/get?key1=value1&key2=value2&key2=value3

2 定制请求头

        请求头Headers提供了关于请求相应或其他发送实体的信息。如果没有指定请求头或者请求的请求头和实际网页不一致,就可能无法返回正确的结果。
        对于定制请求头,只需要简单的传递一个 dict 给 headers 参数就可以了。

        那么如何找到正确的Headers呢?
        首先,用Chrome浏览器打开要求请的网页,右击网页的任意位置,单击“检查”,会弹出下图所示的工作区。

         接着,在该工作区中,点击Network选项,这是可能会什么也没有,那么刷新网页,得到如下图所示的页面。

         在左侧的资源中找到需要请求的网页并单击,这是在Headers中可以看到Requests Headers的详细信息。

         提取请求头的重要部分,可以将代码改为:

import requests

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'
}

r = requests.get('https://docs.python-requests.org/zh_CN/latest/user/quickstart.html#id2', headers=headers)
print("响应状态码:", r.status_code)

3 发送POST请求

        除了get请求之外,有时需要发送一些编码为表单形式的数据,要实现这个,只需使用post请求,并简单地传递一个字典给 data 参数。

payload = {'key1': 'value1', 'key2': 'value2'}

r = requests.post("http://httpbin.org/post", data=payload)
print(r.text)
# {
#   ...
#   "form": {
#     "key2": "value2",
#     "key1": "value1"
#   },
#   ...
# }

        还可以为 data 参数传入一个元组列表。在表单中多个元素使用同一 key 的时候,这种方式尤其有效:

payload = (('key1', 'value1'), ('key1', 'value2'))
r = requests.post('http://httpbin.org/post', data=payload)
print(r.text)
# {
#   ...
#   "form": {
#     "key1": [
#       "value1",
#       "value2"
#     ]
#   },
#   ...
# }

4 超时

        可以告诉 requests 在经过以 timeout 参数设定的秒数时间之后停止等待响应。注意,timeout  仅对连接过程有效,与响应体的下载无关。 timeout 并不是整个下载响应的时间限制,而是如果服务器在timeout 秒内没有应答,将会引发一个异常。

requests.get('http://github.com', timeout=0.001)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request #timed out. (timeout=0.001)

四、 案例:爬取TOP250电影数据

目的:获取豆瓣电影TOP250的所有电影名称,网页地址为豆瓣电影 Top 250

1 网页分析

        打开豆瓣电影TOP250的网站,使用“检查”功能查看该网页的请求头,如下图所示

提取重要的请求头:

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
        'Host': 'movie.douban.com'
    }

         由页面可以看到,第一页只有25个电影,要想获取所有电影名称,需获取10页的内容。现在分析每页内容的网址地址。
        单击第二页可以发现网页地址变为:https://movie.douban.com/top250?start=25
        单击第三页可以发现网页地址变为:https://movie.douban.com/top250?start=50
        因此每多一页,就给网页地址的start参数加上25

2 获取网页

        利用requests获取网页的内容:

import requests

def get_movies():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
        'Host': 'movie.douban.com'
    }
    for i in range(0, 10):
        link = 'https://movie.douban.com/top250?start=' + str(i * 25)
        r = requests.get(link, headers=headers, timeout=10)
        print(str(i + 1), "页响应状态码:", r.status_code)
        print(r.text)

if __name__ == '__main__':
    get_movies()

如此,得到的结果只是网页的HTML代码。

3 解析网页

        解析网页的内容会在后续介绍。在这,给出解析网页的代码:

import requests
from bs4 import BeautifulSoup


def get_movies():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
        'Host': 'movie.douban.com'
    }
    movie_list = []
    # div_list = []
    for i in range(0, 10):
        link = 'https://movie.douban.com/top250?start=' + str(i * 25)
        r = requests.get(link, headers=headers, timeout=10)
        print(str(i + 1), "页响应状态码:", r.status_code)
        # print(r.text)
        soup = BeautifulSoup(r.text, "lxml")
        div_list = soup.find_all('div')
        for each in div_list:
            movie = each.a.span.text.strip()
            movie_list.append(movie)
    return movie_list

if __name__ == '__main__':
    get_movies()

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值