今日考题
1.详述豆瓣top250爬取思路(尽可能详细一些)
# 以由外到内的思维方法为例
1.观察所需网页加载方式 为直接加载的
2.先找到每个电影是通过li布局再页面上的 先获取到整个li列表
3.再通过xpath选择器选取到所需标签
4.只有遇到没有短评的部分会比较麻烦可以找到其位置之后用xpath选择器选出后对结果进行判断
5.如果结果为空就输出'暂无短评'如果有元素就使用原来的元素
6.最后将所有列表通过zip整合成拥有所有信息的大列表通过append写入表格
2.详述xpath选择器基本使用
from lxml import etee # 首先总归是要导入模块
res = ...
html = etree.HTML(res.text) # 解析步骤 硬记
a1 = html.xpath('里面放xpath能听懂的语句')
a2 = html.xpath('//div') # 页面中所有div标签 最前面的//匹配全局
a3 = html.path('//body/div') # body标签中的儿子div /表示儿子
a4 = html.xpath('//body//a[@href=...]') # body标签中的后代a标签且href为... //表示后代 中括号加@用于匹配属性
a5 = html.xpath('//body//a/@href') # /@href 表示获取前面所选到标签的href href可以替换成任意属性字段
a5 = html.xpath('//body//a[1]/text()') # 取符合条件的第一个a标签的文本
a6 = html.xpath('//body//a[contains(@class,"beauty","sexy")]') # 当有多个class属性不能直接用= 需要像这样用contain
a7 = html.xpath('//body//a[contains(@class,"beauty") and @name="zyy"]') # 前面条件内class含有beauty并且name=zyy的a标签
a8 = html.xpath('//a[last()]') # 取最后一个a标签
a9 = html.xpath('//a[last()-2]') # 取最后一个再向前数两个的a标签即倒数第三个
a10 = html.xpath('//a[position()<3]') # 取位置小于3的a标签即前两个
复习巩固
- 豆瓣top250
注意事项
1.需要校验User-Agent
2.针对IP的防爬措施管控十分严格
1.研究数据加载规律发送请求
2.针对所需数据研究规律 解析之后爬取
3.利用openpyxl写入表格
4.研究多页规律加上翻页
- xpath选择器
使用简单 逻辑顺滑 效率高
需要先下载模块
pip3 install lxml
导入模块
from lxml import etree
使用语法
tree = etree.HTML(...)
'''py文件的名称不能和模块名冲突'''
常用方法
在考题中可以具体查看
- 猪八戒爬取
可以活用浏览器的copy来复制解析器所需的语句
有广告和页面上所需数据的布局混合在了一起需要将其分别出来
今天就来解决这个问题
内容概要
- 爬取城市名称
- 爬取猪八戒数据并写入表格
- 爬贴吧图片
- 自动化测试工具selenuim模块
详细讲解
爬取城市名称
import requests
from lxml import etree
'''
1.首先查看网址不难发现数据是直接写在网页上的
2.城市部分被两大块div分割开来 那就将这两页分开爬取
'''
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',
'Referer': 'https://www.aqistudy.cn/historydata/'}
res = requests.get('https://www.aqistudy.cn/historydata/',
headers=headers)
# print(res.text)
etree = etree.HTML(res.text)
hot_city_list = etree.xpath('/html/body/div[3]/div/div[1]/div[1]/div[2]/ul/li/a/text()')
# print(hot_city_list)
hot_city_link_list = etree.xpath('/html/body/div[3]/div/div[1]/div[1]/div[2]/ul/li/a/@href')
# print(hot_city_link_list)
normal_city_list = etree.xpath('/html/body/div[3]/div/div[1]/div[2]/div[2]/ul/div[2]/li/a/text()')
# print(normal_city_list)
all_city = etree.xpath(
'/html/body/div[3]/div/div[1]/div[1]/div[2]/ul/li/a/text() | /html/body/div[3]/div/div[1]/div[2]/div[2]/ul/div[2]/li/a/text()')
print(all_city) # xpath通过|吧两个结果取了个or 相当于正则的| 满足前半部分的可以后半部分也可以 非常好用
# base_url = 'https://www.aqistudy.cn/historydata/'
# url = base_url + hot_city_link_list
# res1 = requests.get(url, headers=headers) # 通过这步可以请求到网页内部
# # 但是关键数据是动态加载的呀我佛了 以后技术高超了再来考虑
猪八戒全局查找
import requests
from lxml import etree
from openpyxl import Workbook
wb = Workbook()
wb1 = wb.create_sheet('外包', 0)
wb1.append(['公司名称', '价格', '成交数', '业务范畴', '详情链接'])
work = input('请输入你想要的业务').strip()
res = requests.get('https://shanghai.zbj.com/search/f/',
params={'kw': work})
x_html = etree.HTML(res.text)
'''
尝试了一下硬是用全局查找来做
也不是不可以就是通过class做出明确的限定写的长一点
'''
company_tag_list = x_html.xpath('//div[contains(@class,"item-wrap") and contains(@class,"service-new") and contains(@class,"j-sp-item-wrap ")]/div[1]/div[1]/a[1]/div[1]/p/text()')
# print(company_tag_list)
company_list = []
for company_tag in company_tag_list:
if len(company_tag)<5:
continue
else:
company_list.append(company_tag.strip('\n'))
print(company_list)
# //*[@id="utopia_widget_76"]/a[2]/div[2]/div[1]/span[1]
price_list = x_html.xpath('//div[contains(@class,"item-wrap") and contains(@class,"service-new") and contains(@class,"j-sp-item-wrap ")]/div[1]/div[1]/a[2]/div[2]/div[1]/span[1]/text()')
# print(price_list)
deal_num_list = x_html.xpath('//div[contains(@class,"item-wrap") and contains(@class,"service-new") and contains(@class,"j-sp-item-wrap ")]/div[1]/div[1]/a[2]/div[2]/div[1]/span[2]/text()')
item_include_list = x_html.xpath('//div[contains(@class,"item-wrap") and contains(@class,"service-new") and contains(@class,"j-sp-item-wrap ")]/div[1]/div[1]/a[2]/div[2]/div[2]/p[1]/text()')
link_list = x_html.xpath('//div[contains(@class,"item-wrap") and contains(@class,"service-new") and contains(@class,"j-sp-item-wrap ")]/div[1]/div[1]/a[2]//@href')
# # print(link_list)
full_info_list = zip(company_list, price_list, deal_num_list, item_include_list, link_list)
for full_info in full_info_list:
# # print(full_info)
wb1.append(list(full_info))
wb.save(r'八戒八戒.xlsx')
百度贴吧图片
import requests
from lxml import etree
import os
import time
name = input('请输入想要爬取的贴吧名>>>:').strip()
if not os.path.exists(name):
os.mkdir(name)
page_str = input('请输入你要爬取的代码页数>>>:').strip()
page = (int(page_str) - 1) * 50
res = requests.get('https://tieba.baidu.com/f',
params={'kw': name,
'pn': page}
) # 通过额外参数控制贴吧和页数
# print(res.text)
tree = etree.HTML(res.text)
second_link_list = tree.xpath('//a[@class="j_th_tit "]/@href') # 筛选出所有帖子的链接部分
base_url = 'https://tieba.baidu.com'
for link in second_link_list:
url = base_url + link # 拿到一个个帖子的链接之后拼接获取完整网址
res1 = requests.get(url) # 访问一个个帖子的网址
tree1 = etree.HTML(res1.text)
img_link_list = tree1.xpath('//img[@class="BDE_Image"]/@src') # 筛选出帖子里图片的链接部分
for img_link in img_link_list:
res2 = requests.get(img_link) # 访问一个个图片的网址
file_path = os.path.join(name, img_link[-10:]) # 起名从后往前拿保证拿到.jpg
with open(file_path, 'wb') as f:
f.write(res2.content) # 写入保存
time.sleep(1)
selenium模块
原本仅仅是测试领域里面的一款测评工具
但是由于其可以操作浏览器
所以也被应用到了爬虫领域
1.模块下载
pip3 install selenium
2.驱动下载
该模块是用来操作浏览器的 需要相应的驱动4
http://npm.taobao.org/mirrors/chromedriver/2.38/
'''
1.有时候下载了驱动可能也无法操作浏览器
原因:可能是因为驱动版本不对
措施:重新一个版本的驱动
2.不同的浏览器需要下载不同的驱动文件
'''
3.驱动文件的存放位置
1.当前编程环境下 只有现在这个文件能用
2.任意位置只要能记住绝对路径 每次用要从绝对路径调用很不方便
3.存放到python解释器scripts文件夹内即可 一劳永逸
4.验证可以使用
from selenium import webdriver # 倒一下模块
import time
bro = webdriver.Chrome() # 指定操作的浏览器驱动
bro.get("http://www.baidu.com") # 控制浏览器访问网站数据
time.sleep(3) # f防止太快看不到变化
bro.close() # 关闭浏览器窗口
基本操作使用
'''
这个模块的所有功能都很容易理解基本搂一眼就知道是干什么的了
find_element与find_elements的区别相当于bs4模块里面的find与find_all
'''
# 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选择
B站小案例
from selenium import webdriver # 倒一下模块
import time
from selenium.webdriver.common.keys import Keys # 导入键盘按键操作
bro = webdriver.Chrome() # 指定操作的浏览器驱动
bro.get("https://www.bilibili.com/") # 控制浏览器访问网站数据
input_tag = bro.find_element_by_id('nav_searchform') # 找到B站的输入框
time.sleep(1)
input_tag.send_keys('小潮院长') # 输入框搜索想要内容
time.sleep(1)
input_tag.send_keys(Keys.ENTER) # 输入框敲回车
time.sleep(5) # 防止太快看不到变化
bro.close() # 关闭浏览器窗口