爬取城市名、猪八戒、贴吧图片和selenuim模块
xpath相关练习和selenuim模块
-
-
爬取猪八戒数据并写入表格
-
爬取贴吧图片数据
-
爬取城市名
目的网址:https://www.aqistudy.cn/historydata/
思路
1,查看详细页面,查看数据加载方式 2,查看network获取url,请求方式获取,请求体信息需要请求值
3,根据网络源码的信息布局获取页面,选择适合的选择器和解析方法
代码
# 调用模块 import requests from lxml import etree
发现数据为直接加载
查看network寻找请求头信息
# 发送请求获取页面数据 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/94.0.4606.61 Safari/537.36" } ) # 构造对象 city_list= etree.HTML(res.text) # 获取热门城市 hot_city=city_list.xpath('/html/body/div[3]/div/div[1]/div[1]/div[2]/ul/li/a/text()') print(hot_city)
# 获取其他城市 other_city=city_list.xpath('/html/body/div[3]/div/div[1]/div[2]/div[2]/ul/div[2]/li/a/text()') print(other_city)
思考如何爬取详细页面数据
由于详情页面存在js代码阻止爬取数据,以现有知识很难获取
爬取猪八戒
需求:公司名称 地址 价格 成交量 描述信息思路
1.打开网址,查看数据加载方式 2.发现是直接加载,查看请求方式,可以直接向网址发送请求,获取相关请求体信息 3.获取数据后,选用喜欢的模块来获取相关数据
执行
# 调用用模块 import requests from bs4 import BeautifulSoup from lxml import etree from openpyxl import Workbook # 构造表格对象 wb=Workbook() # 构造工作簿 wb1=wb.create_sheet('猪八戒',0) # 创建表头文件 wb1.append(['价格','公司','接单数','详细信息','地址'])
发现数据为直接加载,通过network查看url和请求方式
# 发送get请求 res=requests.get('https://shanghai.zbj.com/search/f/?', params={"kw": "python"} ) # 构造对象 zhu_html=etree.HTML(res.text) # 先查找所有的外部div标签 zhu_div=zhu_html.xpath('/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div') # 循环获取div for div in zhu_div: # 获取价格 zhu_price=div.xpath('.//span[@class="price"]/text()') # 获取公司名 zhu_name=div.xpath('./div/div/a[1]/div[1]/p/text()') # 获取接单数 zhu_num =div.xpath('./div/div/a[2]/div[2]/div[1]/span[2]/text()') # 获取详细信息 zhu_info=div.xpath('.//div/a[2]/div[2]/div[2]/p/text()') # 获取地址 zhu_address=div.xpath('./div/div/a/div[1]/div/span/text()')
# 名字的格式不都一样 try: # 将名字中多余部分去除 name=zhu_name[1].strip('\\n') # 如果发生错误 except Exception as f: # 名字为空 name='' # 名字的格式不都一样,无法获取 try: # 输入信息 wb1.append([zhu_price[0],name,zhu_num[0],zhu_info[0],zhu_address[0]]) except Exception as f: continue # break # 保存文件 wb.save('猪八戒.xlsx')
结果
防止被封只获取一个
爬取贴吧图片
思路
1.打开页面查看加载方式,发现是动态加载,当前页面的图片为假的 2.但可以获得各个帖子的url地址,打开network查看加载方式,和请求体等信息 3.向地址发送请求,循环获取贴吧地址,贴吧地址不完整,需要拼接 4.进入详细页面,发现图片为直接加载 5.发现帖子的img标签都为class=“BDE_Image”, 6.查看network查看加载方式,和请求体等信息
代码
''' 执行代码要做停顿百度会封IP '''
# 调用模块 import requests from lxml import etree import os import time
通过观察发现贴吧网址通过kw参数控制贴吧名,pn参数控制页数,50为第二页,100为第三页
# 获取用户想要爬取的贴吧名称
tieba = input('请输入贴吧的名称:').strip()
# 获取页数
page_num=int(input('要多少页:').strip())
# 判断当前贴吧名称是否存在对应的文件夹
if not os.path.exists(tieba):
# 创建文件
os.mkdir(tieba)
# 设置默认值
i=0
# 循环获取个页面
while i <=page_num:
# 页面成50
now_page=i*50
# 发送请求
res = requests.get('https://tieba.baidu.com/f?kw=%s&ie=utf-8&pn=%s'%(tieba,now_page),
)
# 生成对象
tree = etree.HTML(res.text)
# 查找链接地址
a_link_list = tree.xpath('//a[@class="j_th_tit "]/@href')
base_url = 'https://tieba.baidu.com'
# 循环获取每一个帖子链接 拼接成完整的地址 再发送请求
for link in a_link_list:
# 拼接完整地址
full_link = base_url + link
print(full_link)
# 发送详情页请求获取页面数据
res1 = requests.get(full_link)
tree1 = etree.HTML(res1.text)
# 筛选图片链接
img_src_list = tree1.xpath('//img[@class="BDE_Image"]/@src')
# 循环请求每个图片地址
for img_src in img_src_list:
print(img_src)
# 发送请求
res2 = requests.get(img_src)
# 拼接路径
file_path = os.path.join(tieba,img_src[-15:])
# 打开文件以二进制模式写入
with open(file_path,'wb') as f:
# 写入图片
f.write(res2.content)
# 暂停一秒
time.sleep(1)
# 在此只获取一个图片
break
# 页数加一
i+=1
# 同上道理怕被封
break
结果
本来是测试领域里面的一款测试工具,由于其可以操作浏览器所以也被应用到了爬虫领域
优点:可以避免很多防爬措施
缺点:但是由于需要操控浏览器所以效率慢
模块下载
pip3 install selenium
驱动器下载
该模块是用来操作浏览器的 需要相应的驱动软件
""" 注意:有时候下载了驱动可能也无法操作浏览器 原因:可能是因为驱动版本不对 措施:重新一个版本的驱动 注意:不同的浏览器需要下载不同的驱动文件 """
下载网址:http://npm.taobao.org/mirrors/chromedriver/2.38/
选择符合操作系统的软件,Windows版兼容32位和64位的
下载之后软件存放位置需注意 ''' 1.当前编程环境下(不推荐) 2.任意位置只要能记住绝对路径(不推荐) 3.存放到python解释器scripts文件夹内即可(推荐) '''
seleuinm模块使用
模块调用
from selenium import webdriver import time
指定操作的浏览器驱动
语法:
变量名=webdriver.浏览器名()
eg:
bro = webdriver.Chrome()
控制浏览器访问网站数据
语法:
变量.get("网址")
eg:
# 访问百度
bro.get("http://www.baidu.com")
关闭浏览器窗口
语法:
变量.close()
eg:
# 关闭浏览器 bro.close()
基本操作
""" find_element与find_elements的区别就在于前者只会找到符合条件的第一个 后者是所有 两者的关系相当于bs4模块里面的find与find_all """
find_element_by_id 根据id找
print(bro.find_element_by_id('s-top-left'))
find_element_by_link_text 根据链接名字找到控件(a标签的文字)
print(bro.find_element_by_link_text('新闻'))
find_element_by_partial_link_text 根据链接名字找到控件(a标签的文字)模糊查询
bro.get("https://tieba.baidu.com/p/7556165760") # 模糊匹配带有乖乖的a标签 print(bro.find_element_by_partial_link_text('乖乖').text)
find_element_by_tag_name 根据标签名
bro.get("https://tieba.baidu.com/f?ie=utf-8&kw=90%E5%90%8E%E7%BE%8E%E5%A5%B3") print(bro.find_element_by_tag_name('a').text)
bro.get("https://tieba.baidu.com/f?ie=utf-8&kw=90%E5%90%8E%E7%BE%8E%E5%A5%B3") print(bro.find_elements_by_tag_name('a'))
find_element_by_class_name 根据类名
print(bro.find_element_by_class_name('j_th_tit ').text)
find_element_by_name 根据属性名
find_element_by_css_selector 根据css选择器
find_element_by_xpath 根据xpath选择
小案例
使用seleuinm模块模拟浏览器打开淘宝搜索iPhone手机
# 调用模块 from selenium import webdriver from selenium.webdriver.common.keys import Keys # 键盘按键操作 import time # 构造对象 bro = webdriver.Chrome('D:\python3.6.8\Scripts\chromedriver.exe') # 打开淘宝 bro.get('https://www.taobao.com/') # 查找搜索框标签 input_tag = bro.find_element_by_id('q') # 输入文本内容 input_tag.send_keys('iphone手机') time.sleep(1) # 点击搜索 input_tag.send_keys(Keys.ENTER) time.sleep(5) # 关闭浏览器 bro.close()