介绍
网络爬虫是一种从互联网抓取信息的自动化程序,通过爬虫程序对网页进行抓取、解析、存储。
使用
1、抓取:通过请求网页 URL,下载网页内容并转换为字符串。(可使用 urllib、requests 等库)
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib.request
import urllib.parse
import requests
# 方法一:通过 Python 内嵌的 urllib 库抓取
def urllib_req(url):
# ********** 抓取 GET 类型无参教 URL **********
response = urllib.request.urlopen(url)
# 获取状态码,200 表示成功
print(response.getcode())
# 获取网页内容
content = response.read()
# 获取网页内容长度
print(len(content))
# ********** 抓取 GET 类型有参教 URL **********
# data = {'data1': 'xxxxxx', 'data2': 'xxxx'}
# params = urlib.parse.urlencode(data)
# url = url + '?' + params
# response = urllib.requests.urlopen(url)
# 方法二:通过第三方库 requests 抓取
def requests_req():
# ********** 抓取 GET 类型无参教 URL **********
response = requests.get(url)
# 获取状态码,200 表示成功
print(response.status_code)
# 获取网页内容
content = response.content
# 获取网页内容长度
print(len(content))
# ********** 抓取 GET 类型有参教 URL **********
# data = {'data1': 'xxxxxx', 'data2': 'xxxx'}
# params = requests.get(url, params=data)
# ...
if __name__ == '__main__':
url = 'http://www.xxx.com'
urllib_req(url)
requests_req(url)
2、解析:将抓取的字符串按正则表达式或 DOM 树的形式解析,可用 html.parser、beautifulsoup 等库。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
Tips:
beautifulsoup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库,可搭配多种解析器使用。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| 解析器 | 使用方法 | 优势 | 劣势 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| Python 标准库 | BeautifulSoup(markup, "html.parser") | 内置标准库、执行速度适中、文档容错能力强 | Python2.7.3 or 3.2.2 前的版本中文容错差 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| LXML HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快、文档容错能力强 | 需安装 C 语言库 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| LXML XML 解析器 | BeautifulSoup(markup, "xml") | 速度快、唯一支持 XML 的解析器 | 需安装 C 语言库 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
| html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性、以浏览器方式解析文档、生成HTML5格式文档 | 速度快、不依赖外部拓展 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
"""
import re
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
# 1.创建解析对象
soup = BeautifulSoup(html_doc, "lxml", from_encoding="utf-8")
# 2.寻找目标节点(下面列举常用的寻找节点的方法)
## 2.1 节点选择
print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
## 2.2 嵌套选择
print(soup.head.title.string)
## 2.3 关联选择
print(soup.title.next_sibling) # 获取节点向下的一个兄弟节点
print(soup.title.previous_sibling) # 获取节点向上的一个兄弟节点
print(soup.title.next_siblings) # 获取节点向下的所有兄弟节点
print(soup.title.previous_siblings) # 获取节点向上的所有兄弟节点
## 2.4 方法选择
print(soup.find(name='p'))
print(soup.find(attrs={'class': 'title'})
print(soup.find(text=re.compile('.*?o.*?', re.S)) # 返回匹配正则的第一个节点的文本
## 2.5 CSS 选择
print(soup.select('.panel .panel-heading'))
print(soup.select('li li'))
print(soup.select('#list-2 .element'))
案例
import requests
from bs4 import BeautifulSoup
import csv
# 设置请求头,模拟浏览器请求
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.74'
}
# 网页的URL
url = "https://movie.douban.com/top250"
# 创建一个空的列表,用于存储所有电影的数据
movie_data = []
# 循环遍历每一页
for i in range(10):
# 构造请求URL
page_url = url + '?start=' + str(i * 25) + '&filter='
# 发送请求
response = requests.get(page_url, headers=headers)
# 创建一个BeautifulSoup对象
soup = BeautifulSoup(response.text, 'html.parser')
# 找到所有电影的元素
movies = soup.select('.item')
# 遍历每个电影元素,并获取数据
for movie in movies:
# 获取电影名
title = movie.select_one('.title').text.strip()
# 获取导演、类型、制片国家/地区、上映日期等信息
info = movie.select_one('.bd').text.strip().split('\n')
director = info[0].split('导演: ')[1].split('主演:')[0].strip()
genres = info[1].strip().split(' / ')
country = info[2].strip()
date = info[1].split(' / ')[-1]
# 获取评分
rating = movie.select_one('.rating_num').text.strip()
# 获取IMDb编号
imdb_url = movie.select_one('.hd a')['href']
imdb_id = imdb_url.split('/')[-2]
# 将所有数据存储为一个字典
movie_dict = {
'电影名': title,
'导演': director,
'类型': genres,
'制片国家/地区': country,
'上映日期': date,
'评分': rating,
'IMDb编号': imdb_id
}
# 将字典添加到电影数据列表中
movie_data.append(movie_dict)
# 将数据保存到CSV文件中
with open('douban_top250.csv', 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['电影名', '导演', '类型', '制片国家/地区', '上映日期', '评分', 'IMDb编号']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for movie in movie_data:
writer.writerow(movie)
print('数据已保存到douban_top250.csv文件中!')
参考
👏 更多技术资料、原创教程,关注公众号:火星教程