9/28

今日考题
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)  # 通过这步可以请求到网页内部
# # 但是关键数据是动态加载的呀我佛了 以后技术高超了再来考虑

9/28

猪八戒全局查找

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')

9/28

百度贴吧图片

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)

9/28

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()  # 关闭浏览器窗口

9/28

基本操作使用

'''
这个模块的所有功能都很容易理解基本搂一眼就知道是干什么的了
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()  # 关闭浏览器窗口
上一篇:10>>>解析库之Xpath解析器


下一篇:ionic