11>>>xpath实战、selenium模块

11.xpath实战、selenium模块

 

xpath爬取城市数据

地址:https://www.aqistudy.cn/historydata/
需求:爬取热门城市及其他城市

思路:

1.研究数据加载规律发送请求

  经过研究后发现是直接加载数据的,可以直接向网页发出get请求。

2.针对所需数据研究规律使用xpath解析

  热门城市在div class="hot" 中,其他城市在div class="all"中。

11>>>xpath实战、selenium模块

  寻找热门城市的xpath语句:

hot_city = tree.xpath('//div[@class="hot"]/div[2]/ul/li/a/text()')

 

11>>>xpath实战、selenium模块

  寻找全部城市的xpath语句:

all_city = tree.xpath('//div[@class="all"]/div[2]/ul/div[2]/li/a/text()')

  使用xpath的规律就在于先明确你需要查找的标签,之后往上多看几层具有一定特征的父标签,之后依次逐层查找即可。

完整代码:

11>>>xpath实战、selenium模块
import requests
from lxml import etree
​
# 1.发送请求获取页面数据
res = requests.get("https://www.aqistudy.cn/historydata/",
                      headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'})
# 2.查看是否有防爬和编码问题
# print(res.text)  # 校验User-Agent
# 3.生成一个xpath对象
tree = etree.HTML(res.text)
# 4.研究标签规律,书写xpath提取对应数据
# 获取热门城市
hot_city = tree.xpath('//div[@class="hot"]/div[2]/ul/li/a/text()')
# 获取全部城市
all_city = tree.xpath('//div[@class="all"]/div[2]/ul/div[2]/li/a/text()')
# 一次性查找所有的城市名称(拼接列表)
citys_name = tree.xpath('//div[@class="hot"]/div[2]/ul/li/a/text() | //div[@class="all"]/div[2]/ul/div[2]/li/a/text()')
print(citys_name)
View Code

 

Xpath爬取猪八戒数据

这个网站昨天我们试过,所以今天就单刀直入讲过程了。

地址:shanghai.zbj.com/search
需求:公司名称、地址、价格、成交量、描述信息,并且保存为excel文件

思路:

1.研究数据加载规律发送请求

  经过研究后发现是直接加载数据的,可以直接向网页发出get请求。

2.针对所需数据研究规律使用xpath解析

  每个项目都在class="new-service-wrap"中,只需逐一查找各个内容所在的标签即可。

3.再利用openpyxl模块写入数据

4.研究分页规律持久化多页数据

完整代码:

11>>>xpath实战、selenium模块
import requests
from lxml import etree
from openpyxl import Workbook
​
# 建立excel文件
wb = Workbook()
wb1 = wb.create_sheet('订单数据', 0)
wb1.append(['公司名称', '公司地址', '订单价格', '历史成交', '订单描述'])  # 定义表头
​
# 1.发送请求获取页面数据
res = requests.get('https://shanghai.zbj.com/search/f/',
                   params={'kw': 'python'})
# 2.生成xpath对象
tree = etree.HTML(res.text)
# 3.研究标签规律,书写xpath
# 先查找所有含有数据的div,然后依次循环
div_list = tree.xpath('//div[@class="new-service-wrap"]/div')
for div in div_list:
    # 3.1公司名称
    origin_comp_name = div.xpath('./div/div/a/div[1]/p/text()')
    # 在该网站上有广告位,所以可以先筛选掉
    if not origin_comp_name:
        continue
    comp_name = origin_comp_name[-1].strip('\n')
    # 3.2公司地址
    origin_address = div.xpath('./div/div/a/div[1]/div/span/text()')
    address = origin_address[0]
    # 3.3订单价格
    origin_price = div.xpath('./div/div/a[2]/div[2]/div[1]/span[1]/text()')
    price = origin_price[0]
    # 3.4历史成交
    origin_duel_num = div.xpath('./div/div/a[2]/div[2]/div[1]/span[2]/text()')
    duel_num = origin_duel_num[0]
    # 3.5订单描述
    origin_desc = div.xpath('./div/div/a[2]/div[2]/div[2]/p/text()')
    desc = 'python'.join(origin_desc)  # 上一步筛选出来的数据会少掉python字符串,所以这里加上
    wb1.append([comp_name, address, price, duel_num, desc])  # 将所有数据写入excel文件中
​
# 保存excel文件
wb.save(r'猪八戒订单数据.xlsx')
View Code

 

Xpath爬取贴吧图片数据

需求:
1.贴吧名称是用户自己指定,不是固定的一个。
2.所有的图片都需要自动保存到以贴吧名称命名的文件夹内

提示:在编写程序的时候我们可以先以一个贴吧为例,程序主体完成之后再换成用户输入即可。贴吧图片支持多页爬取。

前期地址研究

  我们先登录几个贴吧看看规律。

火影忍者吧:https://tieba.baidu.com/f?ie=utf-8&kw=%E7%81%AB%E5%BD%B1%E5%BF%8D%E8%80%85&fr=search
三国全面战争吧:https://tieba.baidu.com/f?ie=utf-8&kw=%E4%B8%89%E5%9B%BD%E5%85%A8%E9%9D%A2%E6%88%98%E4%BA%89&fr=search
潜行者吧:https://tieba.baidu.com/f?ie=utf-8&kw=%E6%BD%9C%E8%A1%8C%E8%80%85&fr=search

  通过分析三个贴吧网址,我们可以看见真正有变化的是kw参数,该参数携带的是一串二进制数据,输入到网站搜索栏后就会自动解码为汉字,所以不用管它们到底是什么意思。

  接着来研究一下页码的规律。

https://tieba.baidu.com/f?kw=%E6%BD%9C%E8%A1%8C%E8%80%85&ie=utf-8&pn=50
第二页
https://tieba.baidu.com/f?kw=%E6%BD%9C%E8%A1%8C%E8%80%85&ie=utf-8&pn=100
第三页
https://tieba.baidu.com/f?kw=%E6%BD%9C%E8%A1%8C%E8%80%85&ie=utf-8&pn=150
第四页

  页码变更的核心就在于pn参数。第一页就是pn=0。

11>>>xpath实战、selenium模块

整体逻辑:先获取每个帖子的链接,之后请求再筛选图片。

注意:度娘和谐力度相当大,一定要记得加上时停,间隔太短依然会有封ip风险!!!

完整代码:

11>>>xpath实战、selenium模块
import requests
from lxml import etree
import os
import time
​
# 获取用户想要爬取的贴吧名称
tieba_name = input('请输入你想要爬取的贴吧名称>>>:').strip()
# 判断当前贴吧名称是否存在对应的文件夹
if not os.path.exists(tieba_name):
    os.mkdir(tieba_name)
​
# 1.发送请求
res = requests.get('https://tieba.baidu.com/f',
                   params={'kw': tieba_name}
                   )
# 2.生成一个xpath对象
tree = etree.HTML(res.text)
# 3.查找所有帖子的链接地址
a_link_list = tree.xpath('//a[@class="j_th_tit "]/@href')
base_url = 'https://tieba.baidu.com'
# 4.循环获取每一个帖子链接 拼接成完整的地址 再发送请求
for link in a_link_list:
    full_link = base_url + link
    # 5.发送详情页请求获取页面数据
    res1 = requests.get(full_link)
    tree1 = etree.HTML(res1.text)
    # 6.筛选图片链接地址
    img_src_list = tree1.xpath('//img[@class="BDE_Image"]/@src')
    # 7.循环请求每个图片地址 并保存图片
    for img_src in img_src_list:
        res2 = requests.get(img_src)
        file_path = os.path.join(tieba_name,img_src[-15:])
        with open(file_path,'wb') as f:
            f.write(res2.content)
    time.sleep(3)
View Code

 

selenium模块

 

准备工作

  selenium模块是一款自动化操作模块,性能没有requests高,两者可以结合使用。

  selenium模块原本仅仅是测试领域中的一款测试工具,但是由于其可以操作浏览器,所以逐步也被应用到了爬虫领域。

  使用selenium模块可以避免很多防爬措施,但由于需要操控浏览器,所以效率上偏慢。

1.模块下载

pip3 install selenium

2.驱动下载(必备条件)

  该模块是用来操作浏览器的,需要相应的驱动软件。

注意:有时候下载了驱动可能也无法操作浏览器

  原因:可能是因为驱动版本不对

  措施:重新一个版本的驱动

注意:不同的浏览器需要下载不同的驱动文件

3.驱动文件的存放位置

1.当前编程环境下(不推荐)
2.任意位置只要能记住绝对路径(不推荐)
3.存放到python解释器scripts文件夹内即可(一劳永逸,推荐)

11>>>xpath实战、selenium模块

4.验证

  接下来我们就可以调用模块验证一下了。

from selenium import webdriver
import time
​
# 指定操作的浏览器驱动
bro = webdriver.Chrome()
# 控制浏览器访问网站数据
bro.get("http://www.baidu.com")
​
# 关闭浏览器窗口
time.sleep(3)
bro.close()

基本操作

# 1、find_element_by_id   根据id找
# div_tag = bro.find_element_by_id('s-top-left')
# 2、find_element_by_link_text     根据链接名字找到控件(a标签的文字)
# a_tag = bro.find_element_by_link_text("新闻")
# 3、find_element_by_partial_link_text   根据链接名字找到控件(a标签的文字)模糊查询
# 4、find_element_by_tag_name       根据标签名
# 5、find_element_by_class_name     根据类名
# 6、find_element_by_name           根据属性名
# 7、find_element_by_css_selector   根据css选择器
# 8、find_element_by_xpath          根据xpath选择

  上述方法都是用来找符合条件的单个数据的,想要找所有符合条件的数据,只需要把与剧中的element改成elements(多加个s)就可以了。

  find_element与find_elements的区别就在于前者只会找到符合条件的第一个数据,后者是所有数据。两者的关系相当于bs4模块里面的find与find_all。

上一篇:一道数学题 : 数列 { bn } 收敛, 证明 { an } 也收敛


下一篇:《通过C#学Proto.Actor模型》之Persistence