欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

L3&L4 第一个爬虫项目

程序员文章站 2022-06-05 19:05:38
...

L3&L4 第一个爬虫项目

1 爬虫的基本步骤

向服务器发送请求-解析网页中源代码-提取数据-保存数据

  1. 向网页发送请求,获取网页源代码;
  2. 导入新的模块,解析网页源代码;
  3. 查看网页中的数据节点;
  4. 解析内容,提取节点的数据;
  5. 学习查找节点的方法,提取节点中的内容。

2 获取网页源代码

想要获取网页中的数据,首先要获取网页 HTML 代码,再把数据从中提取出来。
我们要向网页的服务器发送请求,服务器返回的响应就是网页 HTML 代码。

# TODO 使用import导入requests模块
import requests

# TODO 将URL地址赋值给变量url
url="https://www.baidu.com"

# TODO 将变量url传入requests.get(),赋值给response
response=requests.get(url)

# TODO 使用print输出response
print(response)

3 解析网页源代码

3-1 节点

对于一个网页的节点来说,它可以定义id、class或其他属性,而且节点之间还有层级关系。
我们可以借助网页节点的结构和属性,提取想要的信息。

网页中的每个部分都可以叫做节点。例如:html标签(例如:<h1>标签、<p>标签)、属性、文本等都是一个节点。

3-2 解析工具——BeautifulSoup

BeautifulSoup 是 Python 的一个 HTML 或 XML 的解析模块,可以用它来从网页中提取想要的数据。
BeautifulSoup不是一个内置模块,所以在使用前要先通过代码 pip install bs4 在终端中进行安装。
如果在自己电脑上安装不上或安装缓慢,可在命令后添加 pip install bs4 -i https://mirrors.aliyun.com/pypi/simple/ 进行加速

3-3 lxml 解析器

网络爬虫的最终目的就是过滤选取网络信息,最重要的部分可以说是解析器。解析器的优劣决定了爬虫的速度和效率。
Beautiful Soup 官方推荐我们使用的是 lxml 解析器,原因是它具有更高的效率,所以我们也将采用lxml解析器。
lxml 不是一个内置模块,所以在使用前要先通过代码 pip install lxml 在终端中进行安装。
如果在自己电脑上安装不上或安装缓慢,可在命令后添加 pip install lxml -i https://mirrors.aliyun.com/pypi/simple/ 进行加速。

3-4 创建BeautifulSoup对象

soup = BeautifulSoup(html, "lxml")

第一个参数
是需要解析的 HTML 文本,在这里我们传入变量 html。
第二个参数
是解析器的类型,这里我们使用的是lxml。

# 使用import导入requests模块
import requests

# 从bs4中导入BeautifulSoup
from bs4 import BeautifulSoup

# 将URL地址赋值给变量url
url = "https://www.baidu.com"

# 将变量url传入requests.get(),赋值给response
response = requests.get(url)

# 将服务器响应内容转换为字符串形式,赋值给html
html = response.text

# TODO 使用BeautifulSoup()读取html,添加lxml解析器,赋值给soup
soup=BeautifulSoup(html,"lxml")

# TODO 使用print输出soup
print (soup)

4 解析内容,提取节点的数据

4-1 定位内容所在节点,查看提取内容在源代码中的位置;

文本所在的位置,是包含在<em>XXX</em>这样的节点中,它们都有相同的标签。

我们可以使用 BeautifulSoup 中的 find_all() 函数,获取所有符合指定条件的节点。

4-2 使用find_all() 函数,在代码中查找节点

ps = soup.find_all(name = "h1")

find_all(name=“标签”) 根据标签名查询节点
如果想要获取h1标签所在的节点,可以传入name参数,其参数值为h1 。
name 可以省略,也可以直接传入参数值。
输出的结果是包含所有 h1 节点的列表。

# 使用import导入requests模块
import requests

# 从bs4中导入BeautifulSoup
from bs4 import BeautifulSoup

# 将URL地址赋值给变量url
url = "https://www.baidu.com"

# 将变量url传入requests.get(),赋值给response
response = requests.get(url)

# 将服务器响应内容转换为字符串形式,赋值给html
html = response.text

# 使用BeautifulSoup()读取html,添加lxml解析器,赋值给soup
soup = BeautifulSoup(html, "lxml")

# TODO 使用find_all()查询soup中head的节点,赋值给content_all
content_all=soup.find_all(name="head")

# TODO 使用print输出content_all
print (content_all)

4-3 获取标签内容

# 使用import导入requests模块
import requests

# 从bs4中导入BeautifulSoup模块
from bs4 import BeautifulSoup

# 将URL地址赋值给变量url
url = "https://www.icourse163.org/"

# 将变量url传入requests.get(),赋值给response
response = requests.get(url)

# 将服务器响应内容转换为字符串形式,赋值给html
html = response.text

# 使用BeautifulSoup()读取html,添加lxml解析器,赋值给soup
soup = BeautifulSoup(html, "lxml")

# 使用find_all()查询soup中div的节点,赋值给content_all
content_all = soup.find_all(name="div")

# TODO for循环遍历content_all
for content in content_all:

    # TODO 获取每个节点中标签内的内容,赋值给contentString
    contentString=content.string
    
    # TODO 使用print输出不为None的contentString
    if content.string!=None:
        print (contentString) 

5 学习查找节点的方法,提取节点中的内容

5-1 string属性

.string 属性只能提取单个节点或节点统一的内容。
提取单个节点内容:
例如

<p><em>这是一个段落</em></p>

p 节点包含一个子节点 em ,由于 p 节点有且只有一个子节点,使用 .string 属性时,会输出 em 节点的 .string 内容。

提取节点包含多个子节点时:
当定位的节点中同时包含了多个子节点时,其中有节点是 em 标签内容,其他节点是纯文字。
使用 .string 属性时,不清楚应该调用哪个节点的内容,会返回None值。

# 定义html
html = """
<p>
    <em>网络爬虫</em>
    这是一个段落
</p>"""

# 从bs4中导入BeautifulSoup模块
from bs4 import BeautifulSoup

# 使用BeautifulSoup()读取html,添加lxml解析器,赋值给soup
soup = BeautifulSoup(html, "lxml")

# 使用find_all()查询soup中p节点,赋值给content_all
content_all = soup.find_all(name="p")

# for循环遍历content_all
for content in content_all:

    # TODO 获取每个节点中标签内的内容,赋值给contentString
    content_all=soup.find_all(name="p")
    contentString=content.string
    # 使用print输出contentString
    print(contentString)

5-2 text属性

遇到节点中既包含其他节点,也有文字时,可以使用 .text 属性来提取内容。
.text 属性能直接提取该节点中的所有文字,并返回字符串格式。

# 定义html
html = """
<p>
    <em>网络爬虫</em>
    这是一个段落
</p>"""

# 从bs4中导入BeautifulSoup模块
from bs4 import BeautifulSoup

# 使用BeautifulSoup()读取html,添加lxml解析器,赋值给soup
soup = BeautifulSoup(html, "lxml")

# 使用find_all()查询soup中p节点,赋值给content_all
content_all = soup.find_all(name="p")

# for循环遍历content_all
for content in content_all:

    # TODO 获取节点内的全部内容,赋值给contentString
    contentString = content.text
    
    # 使用print输出contentString
    print(contentString)

6 练习

爬虫去请求网页响应,获取 5 页中全部的用户昵称。
该如何翻页呢? 5 个网页链接大部分内容是相同的,每翻一页page后面的增加1。
第一页:https://www.qiushibaike.com/text/page/1/
第五页:https://www.qiushibaike.com/text/page/5/
整理下思路:

  1. 导入requests和bs4模块;
  2. 使用for循环和格式化字符串的知识,获取5页的URL;
    例如:url = f"https://www.qiushibaike.com/text/page/{num}/"
  3. 将url参数,添加进requests.get()中,获取网页HTML代码;
  4. 创建一个BeautifulSoup对象,使用find_all()函数获取节点;
  5. 调用.string属性,获取每个节点中标签内的内容。
# TODO 使用import导入requests模块
import requests

# TODO 从bs4中导入BeautifulSoup模块
from bs4 import BeautifulSoup

# TODO 使用for循环遍历,range()函数生成的1-5的数字
for num in range(1,6):

    # TODO 利用格式化字符生成串网站链接,赋值给变量url
    url = f"https://www.qiushibaike.com/text/page/{num}/"

    # TODO 将变量url传入requests.get(),赋值给response
    response=requests.get(url)

    # TODO 将服务器响应内容转换为字符串形式,赋值给html
    html=response.text

    # TODO 使用BeautifulSoup()读取html,添加lxml解析器,赋值给soup
    soup=BeautifulSoup(html,"lxml")

    # TODO 使用find_all()查询soup中h2的节点,赋值给name_all
    name_all=soup.find_all(name="h2")

    # TODO for循环遍历name_all
    for name in name_all:

        # TODO 获取每个节点中标签内的内容,赋值给name
        name = name.string

        # TODO print输出name
        print(name)