栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

网络爬虫:从网页访问、爬取 到图片的爬取(学习笔记)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

网络爬虫:从网页访问、爬取 到图片的爬取(学习笔记)

网络爬虫
  • 网页爬取
  • 访问网页
    • requests
    • selenium
  • 解析网页
    • lxml
    • BeautifulSoup
  • 动态网页的爬取
    • requests
    • selenium
  • 图片的爬取

网页爬取

这是一篇自己写的关于爬虫学习过程的笔记。

访问网页 requests

使用requests库主要是用于爬取静态网页,爬取到的源代码仅网页源代码,对于大多数网页而言,即是网页的框架,不包含我们所能在网页上看到的图片、数据等。

import requests
url = 'http://…….com/'        # url为所要爬取的网页网址,以下所有url均隐藏
respond = requests.get(url)   # 请求访问网络
respond.status_code           # 状态的编码
respond.text                  # 响应,获取网页源代码(HTML)
respond.content               # 网页源代码,bytes类型
respond.encoding              # 可改变读取网页的编码格式

headers = {'user_agent':'Mozilla/5.0 (Windows ……(省略)}   # 在开发者工具出可以找到访问所使用的一系列header
respond2 = requests.get(url, headers=headers, timeout=2.)   # 改变hearders,使得访问更像真实浏览器;超过2秒不再访问

除了get方法,还有别的方法向网页发送请求,可以在开发者工具中查找当前网页的请求方法。

selenium

anaconda的python环境中并没有安装到selenium的库,有其他博文专门写了专门安装库,及其插件,在此处就不赘述了,自行查找资料安装。
此处打开的是微软Microsoft Edge浏览器。

from selenium import webdriver
driver = webdriver.Edge()      # 打开浏览器
driver.get(url)          # 打开网页
driver.page_source       # 获取当前动态网页源码,所视数据均被下载,与requests不同
解析网页

解析网页主要有两个方法,lxml 的 etree,和 bs4 的 BeautifulSoup。
然后是定位获取目标元素的方法 xpath 和 select ,
对于xpath和select的索引位置获取,在开发者工具,对想要获取的数据右键,就可以迅速获取:

lxml

lxml在索引时常使用的是xpath。

from lxml import etree
doc = etree.HTML(html)   
 # 解析网页,此处解析网页所使用的文本可以是respond.text 也可以是driver.page_source,或者是导入的源码文件

doc.xpath('/html/body/p/b/text()')   # 通过绝对路径定位目标元素,加text可直接查看文本
doc.xpath('//b/text()')              # 相对路径,获取b下的文本信息
doc.xpath('//p/a/@href')         # 通过@可以获取目标元素属性值
BeautifulSoup

BeautifulSoup也可以使用 lxml 的解析方法,在索引的时候通常使用select而不是xpath。

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'lxml')    # 在 BeautifulSoup也可以使用 lxml 的解析方法

soup.select('html > body > p > b')        # 绝对路径
soup.select('p > b')            # 可以不从最顶级标签写起
soup.select('body a')           # 相对路径不需要 > ,取出body下的所有a
soup.select('p:nth-of-type(2)')         # 取出第二个p标签
soup.select('p > a[id="link1"]')        # 添加具体属性索引不需要加@
souped[0].get('href')      # 获取目标元素属性值,使用 get 函数
动态网页的爬取 requests

动态网页更多可能使用selenium进行获取信息,但是requests也是可以使用的,此时需要先进行逆向分析获得网页网址。

获取到了所需要爬取的数据的网址(记住不是网页网址),再调用get函数访问网站。此时就可以获取到数据的源码。往往获取到的源码是一个json格式的文本,使用json库转换可以直接得到一个字典,但是也要注意查看,这个源码的文本是不是完全符合字典格式,否则转换时会报错。

url_detect = 'https://www.……com.cn/……'      # 获取到的url
respond_detect = requests.get(url_detect)
respond_detect.text

import json
 json.loads(respond_detect.text)       # loads将字符串转为json格式,该字符串的形式可以直接解析成一个列表


若第一个字符不是花括号,要先对字符串进行处理。

selenium
from selenium import webdriver
from bs4 import BeautifulSoup
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import time

url = 'https://www.ptpress.com.cn'
driver = webdriver.Edge()  # 打开浏览器
driver.get(url)            # 打开网页

wait = WebDriverWait(driver, 10)      # 设置等待时长
/confirm/i_btn = wait.until(
    EC.element_to_be_clickable(
        (By.CSS_SELECtOR, '#newBook > div.main > div.tabs > span:nth-child(2)')   
        # 定位要点击的按钮位置
    )
)
/confirm/i_btn.click()   # 执行点击操作
time.sleep(2)         # 暂停一会,等待浏览器响应,再获取对应网页数据

soup = BeautifulSoup(driver.page_source, 'lxml')       # 对点击后的网页获取源码 并 解析
souped = soup.select('#newBook > div.main > div.list > div > div > a > p')      # 取出目标信息

在这里要注意的是,点击之后并不能一下子就获取到新网页的数据,这是因为网页的访问在执行下一条解析程序前还没完成响应,因此会获取到原网页的数据,此时可以使用time.sleep()让程序短暂休眠,以等待网站响应。

import time
time.sleep(2)       # 在点击操作后使用

对于想获得子网页的数据,此时使用selenium就不合适了,selenium 点击后获取的是被点击网页的数据,而不能获取打开的新标签页的数据。这种情况可以使用requests ,逆向分析在源码中找到子网页的网址(即获取目标元素属性值),依次 get 访问再爬取数据。

图片的爬取

第一步:获取网页,发送请求

#1.发送HTTP请求
url = 'http://www/…….com/weimei/index.htm'     # 某个图片网站
respond = requests.get(url)
respond.encoding = 'gbk'  # 更改获取网页的编码方式
                          # 在开发者工具的在console控制台输入document.charset 然后回车可查得网页编码方式
html = respond.text

第二步,获取图片链接 及 图片名称(用于保存图片时命名使用)

#2.网页解析
dom = BeautifulSoup(html)     # document object model
#获取网页壁纸链接
# 法一:select 获取
res = dom.select('#main > div.list > ul > li > a > img')    # 获取全部图片
[i.get('src') for i in res]      # src为img的一个属性,存放了图片的网址
# 法二:xpath 获取
from lxml import etree
dom = etree.HTML(html, etree.HTMLParser())
pic_http = dom.xpath('//*[@id="main"]/div[3]/ul/li/a/img/@src')
# 法三:正则表达式
import re
re.findall('([^<>]{2,})', html)        # 法二:中文可以用非…字符表示,用中括号即对提取的任意字符添加限制条件

第三步:将图片保存到本地

#3.数据保存
# 下载壁纸,并保存到指定路径
url0 = pic_url[0]
# 1 发送请求,获取图片信息,返回python内存空间rl
rq2 = requests.get(url0)
# 2 将内存空间的信息以图片的形式保存到本地
with open('./04-Python网络爬虫-实战/data/text.jpg', 'wb') as f:
    f.write(rq2.content)

#多张图片保存
for url0, title0 in zip(pic_url, pic_names):
    rq = requests.get(pic_url)
    with open('./04-Python网络爬虫-实战/data/{}.jpg'.format(pic_names), 'wb') as f:
        f.write(rq.content)      # 以二进制的形式写入文件

下面封装了三个函数直接爬取:

import requests
from bs4 import BeautifulSoup
import pandas as pd
import os
import re
from lxml import etree
import time

def picture_download(pic_url, pic_title, pic_save_path='./04-Python网络爬虫-实战/data/picture'):
    '''获取并保存图片'''
    rq = requests.get(pic_url)      # 访问图片的url
    with open(pic_save_path + '/{}.jpg'.format(pic_title), 'wb') as f:
        f.write(rq.content)         # 以获取到的图片标题命名文件,保存图片

def get_picture(host_url, encoding='gbk'):
    '''获取同一网页,所有图片的信息'''
    rq = requests.get(host_url)      #访问图片网站
    rq.encoding = encoding           # 更改请求的gbk
    html = rq.text                   # 获取网页源码
    
    dom = etree.HTML(html, etree.HTMLParser())               #解析网页
    pic_url = dom.xpath('//*[@id="main"]//li/a/img/@src')    # 获取图片网址
    pic_titl = dom.xpath('//*[@id="main"]//li/a/b/text()')   # 获取图片标题
    for url0, title0 in zip(pic_url, pic_titl):     # 对网址和标题整合,同时传入函数
        picture_download(url0, title0)

def main():
    '''循环获取多个网页的图片'''
    for i in range(1,66):
        print(f'正在获取第{i}页的壁纸'.center(50, '='))   # 宽度为50,居中,=填充
        if i == 1:      #网页第一页和第二页以后的网址格式不完全相同
            url = 'http://www.…….com/weimei/index.htm'
        else:
            url = 'http://www.…….com/weimei/index_{}.htm'.format(i)
        get_picture(url)
        time.sleep(2)
    print('爬虫结束')
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/272819.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号