Python爬虫

发布于 2022-04-16  769 次阅读


爬虫:模拟浏览器上网,然后让其去互联网抓取数据的脚本。

requests模块

python中原生的一款基于网络请求的模块,功能强大,简单便捷,效率极高。

作用:模拟浏览器发送请求

requests模块的编码流程:

  • 指定url
  • 发起请求
  • 获取响应数据
  • 持久化储存

get请求

import requests

# 指定url
url = 'https://buyunaihe.cn/'
# UA伪装
header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# 处理url携带的参数
param = {
    's':'python'
}
# 发起请求:使用get方法发起请求,该方法返回一个响应对象
response = requests.get(url,params=param,headers=header)
# 获取响应数据:通过调用响应对象的text属性,返回响应对象中储存的字符串形式的响应数据(页面源码)
text = response.text
# 存储数据
with open('demo/data.txt','w',encoding='utf-8') as fp:
    fp.write(text)

post请求

import json
import requests

# 指定url
url = 'https://fanyi.baidu.com/sug'
# UA伪装
header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# 处理url携带的参数
data = {
    'kw':'dog'
}
# 发起请求:使用post方法发起请求,该方法返回一个响应对象
response = requests.post(url,data=data,headers=header)
# 获取响应数据:json()方法返回的是obj(如果确定响应数据是json类型的,才能使用json)
obj = response.json()
# 存储数据
fp = open('demo/data.txt','w',encoding='utf-8')
json.dump(obj,fp,ensure_ascii=False)

数据解析

正则解析

import re

print(re.findall(r'\d+','ab12cd3'))
# ['12', '3']

result = re.finditer(r'\d+','ab12c3')
for item in result:
    print(item.group())
# 12
# 3

bs4解析

1.实例化一个BeautifukSoup对象,并将页面源码加载到该对象中
2.通过调用BeautifulSoup对象相关属性或者方法进行标签定位和数据提取

解析器 使用方法 优势 劣势
Python标准库 BeautifulSoup(markup,"html.parser") Python的内置标准库、执行速度适中、文档容错能力强 Python 2.7.3及Python 3.2.2之前的版本文档容错能力差
xml HTML解析器 BeautifulSoup(markup, "lxml") 速度快、文档容错能力强 需要安装C语言库
lxml XML解析器 BeautifulSoup(markup, "xml") 速度快、唯一支持XML的解析器 需要安装C语言库
html5lib BeautifulSoup(markup, "html5lib") 最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档 速度慢、不依赖外部扩展

通过以上对比可以看出,lxml解析器有解析HTML和XML的功能,而且速度快,容错能力强,所以推荐使用它。

import requests
from bs4 import BeautifulSoup

# 指定url
url = 'https://fanyi.baidu.com'
# UA伪装
header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}

# BeautifulSoup对象实例化
# 1.将本地的html文档加载到BeautifulSoup对象
with open('./test.html','r',encoding='utf-8') as fp:
    soup = BeautifulSoup(fp,'lxml')
# 2.将互联网上获取的页面源码加载到该对象
response = requests.get(url,headers=header)
page_text = response.text
soup = BeautifulSoup(page_text,'lxml')

提供用于数据解析的方法和属性

  • soup.tagName:返回文档中第一次出现tagName对应的标签

  • soup.find()

    • soup.find('tagName'):等同于soup.tagName
    • soup.find('tagName',class_/id/attr =''):属性定位
  • soup.find_all():返回所有,其余和find()相同

  • soup.select('某种选择器'):返回一个列表

xpath解析

最便捷且最高效的解析方式
1.实例化一个etree对象,且需要将被解析的页面内源码加载到该对象。
2.调用etree对象的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。

import requests
from lxml import html

# 指定url
url = 'https://fanyi.baidu.com/sug'
# UA伪装
header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# 1.将本地的html文档加载到etree对象
etree = html.etree.pase('./text.html')
# 2.将互联网上获取的页面源码加载到该对象
response = requests.get(url,headers=header)
page_text = response.text
etree = html.etree.HTML(page_text)

样例

正则

爬取崩坏3所有女武神装甲图片

import re
import os
import requests

# 创建文件夹
if not os.path.exists('./bh3'):
    os.mkdir('./bh3')

# 指定url
URL = 'https://bh3.mihoyo.com/valkyries'
# UA伪装
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}

# 使用通用爬虫对url源码进行爬取
page_text = requests.get(URL, header).text

# 数据解析
# 正则匹配式
ex = r'<a href="(.*?)">'
url_list = re.findall(ex, page_text)
# 发现有且仅有第一个链接是不需要的
url_list.pop(0)

ex1 = r'''<div class="name">
              (.*?)
            </div>'''
ex2 = r'<div class="big-img"><img src="(.*?)">'
for url in url_list:
    sec_url = 'https://bh3.mihoyo.com' + url
    text = requests.get(sec_url, header).text
    # 图片名称
    name = re.findall(ex1, text)[0]
    # 图片地址
    src = re.findall(ex2, text)[0]
    # 图片数据
    data = requests.get(src, header).content
    # 存储路径
    path = './bh3/' + name+'.png'
    with open(path,'wb') as f:
        f.write(data)
        print(name)

bs4

爬取17k小说畅销榜前100

import csv
import requests
from bs4 import BeautifulSoup
from lxml import html

# 指定url
url = 'https://www.17k.com/top/refactor/top100/01_subscribe/01_subscribe__top_100_pc.html'
# UA伪装
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}

# 实例化对象
response = requests.get(url, headers=header)
response.encoding='utf-8'
soup = BeautifulSoup(response.text, 'lxml')

# 数据解析
tr_list = soup.select('body > div.Main.Top100 > div.content.TABBOX > div:nth-child(2) > div:nth-child(1) > table > tr')

# 获取表头
th_list = tr_list[0].select('th')
title = []
for th in th_list:
    title.append(th.text)

infors = [title]

# 获取内容
tr_list.pop(0)
for tr in tr_list:
    td_list = tr.select('td')
    infor = []
    for td in td_list:
        infor.append(td.text)
    infors.append(infor)

# 存储数据
with open('./top100.csv','w',encoding='utf-8-sig',newline='') as f:
    writer = csv.writer(f)
    for infor in infors:
        writer.writerow(infor)

结果

xpath