一周内容回顾(9.27-9.30)
day01
X-path解析器
效率很高,使用广泛
模拟网页内容
View Code导入模块生成对象
# 导入xpath所在模块
from lxml import etree
# 将待匹配的文本传入etree生成一个对象
html = etree.HTML(doc)
主要功能
a = html.xpath('//*') # 匹配所有的标签
a = html.xpath('//head') # 匹配所有的head标签
a = html.xpath('//div/a') # 匹配div标签内部所有的儿子a标签
a = html.xpath('//body//a') # 匹配div标签内容所有的后代a标签
a=html.xpath('//body//a[@href="image1.html"]')
# 属性查找 获取body内部所有的href=image1.html后代a
a = html.xpath('//body//a[@href="image1.html"]/..')
# ..表示查找上一级父标签
'''xpath选择器中中括号内部可以放属性也可以放位置数 从1开始'''
a = html.xpath('//body//a[1]')
查找父标签另外一种形式
a = html.xpath('//body//a[1]/parent::*')
文本获取
获取某个标签内的文本
a = html.xpath('//body//a[@href="image1.html"]/text()')
获取body内部所有后代a内部文本(一次性获取不需要循环)
a = html.xpath('//body//a/text()')
属性获取
获取body内部所有后代a标签href属性值
a = html.xpath('//body//a/@href')
获取title标签id属性值
a = html.xpath('//title/@id')
a = html.xpath('//body//a[2]/@href')
属性多值匹配
a=html.xpath('//body//a[@class="li"]') # 写等号就表示等于,不是包含
a标签有多个class类,直接匹配就不可以了,需要用contains
a = html.xpath('//body//a[contains(@class,"li")]/text()')
多属性匹配
a = html.xpath('//body//a[contains(@class,"li") or @name="items"]')
# 查找body标签内部所有class含有li或者name=items的a标签
# 同理可得
# 查找body标签内部所有class含有li并且name=items的a标签的内部文本
a = html.xpath('//body//a[contains(@class,"li") and @name="items"]/text()')
按序选择
取最后一个
a = html.xpath('//a[last()]/@href')
位置小于3的
# 关键字position() 用于定位
a = html.xpath('//a[position()<3]/@href')
倒数第三个
a = html.xpath('//a[last()-2]/@href')
X-path爬取猪八戒数据
完整代码
import requests from bs4 import BeautifulSoup from lxml import etree from openpyxl import Workbook wb = Workbook() # 构造工作簿 wb1 = wb.create_sheet('猪八戒',0) # 创建表头 wb1.append(['价格','公司','接单数','详细信息']) res = requests.get('https://shanghai.zbj.com/search/f/', params={'kw': 'python'} ) x_html = etree.HTML(res.text) # 查找所有的外部div标签 div_list = x_html.xpath('/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div') # 利用浏览器自动生成 # 循环获取每一个div标签 for div in div_list: price = div.xpath('.//span[@class="price"]/text()') # 价格 company_name = div.xpath('./div/div/a[1]/div[1]/p/text()') # 公司 order_num = div.xpath('./div/div/a[2]/div[2]/div[1]/span[2]/text()') # 接单数 info = div.xpath('./div/div/a[2]/div[2]/div[2]/p/text()') # 详细信息 try: name = company_name[1].strip('\\n') except Exception as f: name = '' try: wb1.append([price[0], name, order_num[0], info[0]]) except Exception as f: continue # 保存文件 wb.save('猪八戒.xlsx')
day02
- 爬取城市名称
- 爬取猪八戒数据并写入表格
- 爬取贴吧图片数据
- 自动化测试工具selenuim模块
爬取城市名称
思路
1.向网页发送请求并携带请求头User-Agent参数
2.生成一个xpath对象并研究标签规律
3.利用xpath选择所需数据
4.打印结果
完整代码
View Code
爬取猪八戒数据并写入表格
思路
1.朝网页发送get请求
2.生成xpath对象
3.研究标签规律,利用xpath模块筛选
4.先查找所有含有数据的div之后依次循环
5.利用解析器xpath筛选所需数据
6.导入openpyxl模块创建表格
7.定义表头以及写入数据最后保存文件
完整代码
import requests from lxml import etree from openpyxl import Workbook wb = Workbook() wb1 = wb.create_sheet('订单数据', 0) wb1.append(['公司名称', '公司地址', '订单价格', '历史成交', '订单描述']) # 1.发送请求获取页面数据 res = requests.get('https://shanghai.zbj.com/search/f/', params={'kw': 'app'} ) # 2.生成xpath对象 tree = etree.HTML(res.text) # 3.研究标签规律 书写xpath div_list = tree.xpath('//div[@class="new-service-wrap"]/div') for div in div_list: # 公司名称 company_name = div.xpath('./div/div/a/div[1]/p/text()') if not company_name: continue # print(company_name[-1].strip('\n')) # 公司地址 address_info = div.xpath('./div/div/a/div[1]/div/span/text()') # print(address_info[0]) # 订单价格 order_price = div.xpath('./div/div/a[2]/div[2]/div[1]/span[1]/text()') # print(order_price[0]) # 历史成交 order_num = div.xpath('./div/div/a[2]/div[2]/div[1]/span[2]/text()') # print(order_num[0]) # 订单描述 order_desc = div.xpath('./div/div/a[2]/div[2]/div[2]/p/text()') # print('app'.join(order_desc)) wb1.append([company_name[-1].strip('\n'), address_info[0], order_price[0], order_num[0], 'app'.join(order_desc)]) wb.save(r'订单数据.xlsx')
爬取贴吧图片数据
需求
贴吧名称是用户自己指定 不是固定的一个
在编写程序的时候可以先以固定的为例之后换成用户输入即可
所有的图片都需要自动保存到以贴吧名称命名的文件夹内
贴吧图片支持多页爬取
思路
1.向网页发送get请求
2.生成一个xpath对象
3.查找所有帖子的链接地址
4.循环获取每一个帖子链接 拼接成完整的地址 再发送请求
5.发送详情页请求获取页面数据
6.筛选图片链接地址
7.循环请求每个图片地址并保存图片
完整代码
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.有时候下载了驱动可能也无法操作浏览器
原因:可能是因为驱动版本不对
措施:重新下一个版本的驱动
# 2.不同的浏览器需要下载不同的驱动文件
驱动文件的存放位置
存放到python解释器scripts文件夹内即可
基本操作
1、find_element_by_id 根据id找
2、find_element_by_link_text 根据链接名字找到控件(a标签的文字)
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选择
结论
find_element与find_elements的区别就在于前者只会找到符合条件的第一个,后者是所有
两者的关系相当于bs4模块里面的find与find_all
小案例
from selenium import webdriver from selenium.webdriver.common.keys import Keys # 键盘按键操作 import time bro = webdriver.Chrome() # 打开淘宝 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()
day03
-
-
图片验证码与滑动验证码的破解思路
-
selenuim其它操作
获取属性
tag.get_attribute('src')
获取文本内容
tag.text
获取标签ID,位置,名称,大小
print(tag.id)
print(tag.location)
print(tag.tag_name)
print(tag.size)
模拟浏览器前进后退
browser.back()
browser.forward()
cookies管理
browser.get_cookies() # 获取cookie
browser.add_cookie({'k1':'xxx','k2':'yyy'}) # 设置cookie
运行js
from selenium import webdriver import time bro=webdriver.Chrome() bro.get("http://www.taobao.com") bro.execute_script('window.scrollTo(0,200)') # 鼠标滚轮移动 time.sleep(5)
选项卡管理
print(browser.window_handles) # 获取所有的选项卡
动作链
方式一
from selenium import webdriver from selenium.webdriver import ActionChains import time driver = webdriver.Chrome() driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') driver.switch_to.frame('iframeResult') # 必须要指定iframe标签 sourse = driver.find_element_by_id('draggable') target = driver.find_element_by_id('droppable') actions = ActionChains(driver) # 拿到动作链对象 actions.drag_and_drop(sourse, target) # 把动作放到动作链中,准备串行执行 actions.perform()
方式二
from selenium import webdriver from selenium.webdriver import ActionChains import time driver = webdriver.Chrome() driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') driver.switch_to.frame('iframeResult') # 必须要指定iframe标签 sourse = driver.find_element_by_id('draggable') target = driver.find_element_by_id('droppable') actions = ActionChains(driver) actions.click_and_hold(sourse) distance = target.location['x'] - sourse.location['x'] track = 0 while track < distance: actions.move_by_offset(xoffset=2, yoffset=0).perform() track += 5 time.sleep(0.5) actions.release() driver.close()
有时候一个页面上还会叠加其他完整的html页面
该页面一般都是iframe标签 内部含有完整的html文档结构
# 在查找该标签内部的标签时需要指定一个参数
driver.switch_to.frame('iframeResult')
滑动验证码
# 针对滑动验证码也是可以通过selenuim自动完成的
# 滑动验证码很多时候不推荐使用程序破解,太过繁琐
很多时候还不如自己亲自手动滑动来的方便
# 滑动验证码在拖动的时候速度不能太快,内部有监测机制
速度过快一步到位会被认为是爬虫程序
无界面操作
from selenium.webdriver.chrome.options import Options from selenium import webdriver chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') driver = webdriver.Chrome(chrome_options=chrome_options) driver.get('https://www.baidu.com') print(driver.page_source)
# 很多程序是可以分辨出来当前浏览器是否被selenuim操作 我们可以在代码中添加如下配置即可避免被识别 from selenium.webdriver import ChromeOptions option = ChromeOptions() option.add_experimental_option('excludeSwitchers',['enable-automation']) driver = webdriver.Chrome(options=option)
第一步使用selenium打开网址,然后让用户完成手工登录,再获取cookie
第二步将获取的cookie数据写入文本文件内
第三步获取cookie中的name和value,转化成requests可以使用的形式
第四步使用该cookie完成请求
完整代码
import requests from selenium import webdriver import time import json # 使用selenium打开网址,然后让用户完成手工登录,再获取cookie # url = 'https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F' # driver = webdriver.Chrome() # driver.get(url=url) # time.sleep(30) # 预留时间让用户输入用户名和密码 # driver.refresh() # 刷新页面 # c = driver.get_cookies() # 获取登录成功之后服务端发返回的cookie数据 # print(c) # with open('xxx.txt', 'w') as f: # json.dump(c, f) cookies = {} with open('xxx.txt', 'r') as f: di = json.load(f) # 获取cookie中的name和value,转化成requests可以使用的形式 for cookie in di: cookies[cookie['name']] = cookie['value'] # # 使用该cookie完成请求 # response = requests.get(url='https://i-beta.cnblogs.com/api/user', cookies=cookies) # response.encoding = response.apparent_encoding # print(response.text)
1.完全使用代码破解
图像识别技术
软件:Tesseract-ocr
模块:pytesseract
2.打码平台
花钱买第三方服务
先使用代码识别如果不想其实还有一帮员工肉眼识别
3.自己人工智能识别
思路
1.寻找任意一个视频地址
2.分析页面在network中发现该地址发送请求后有两个视频和音频文件比较可疑
研究下来发现b站的视频是一分为二的,分为视频和音频
3.然后用requests模块模拟即可,打开文件不停的发送请求加载数据写入即可
思路
1.小说详情页面鼠标左右键全部禁用,但是支持按F12调出控制台
2.研究发现小说文字不是直接加载,于是我们可以查找相关二次请求
3.查找可疑的响应文件,结果发现了两处可疑点,请求体里也有重要参数
4.然后发现文字内容的解密过程发送在浏览器本地,通过浏览器查找相应的js代码,查看该代码内的解密算法
5.怀疑缺失的数据与解析出来js代码有很大的关系,自己新建一个html文件,将content内部拷贝只body内
6.将js代码引入到该html文件夹
7.css反扒破解js注入
day04
- 百度自动登录
- 爬取京东商品数据
- 知乎登录案例
百度自动登录
思路
1.使用谷歌浏览器访问百度首页
2.查找页面上的登录按钮
3.点击登录按钮
4.查找点击短信登录按钮
5.查找手机号输入框并填写内容
6.查找发送验证码按钮并点击
7.查找并点击登录按钮
在访问网站数据的时候加载需要一定的时间,没有加载完全的情况下代码
容易报错 此时需要等待页面数据加载完毕
# 解决措施
bro.implicitly_wait()
完整代码
View Code
爬取京东商品数据
思路
1.访问京东首页并加入延时等待
2.查找搜索款并输入商品名称
3.按下enter键进入商品展示页
4.商品数据的展示页存在动态加载的情况 需要往下滚动
5.循环获取每一个li标签,筛选所需数据
6.图片数据存在懒加载现象
7.最后通过打印展示数据
单页爬取京东商品数据的完整代码
import time from selenium import webdriver from selenium.webdriver.common.keys import Keys bro = webdriver.Chrome() # 1.访问京东首页 bro.get('https://www.jd.com/') bro.implicitly_wait(10) # 延时等待 # 2.查找搜索款并输入商品名称 search_input = bro.find_element_by_id('key') search_input.send_keys('显卡') # 3.按下enter键进入商品展示页 search_input.send_keys(Keys.ENTER) # 由于数据存在滚动加载的现象 for i in range(0, 8000, 1000): # 千万不能直接到底 一定要有一个波段 bro.execute_script('window.scrollTo(0,%s)' % i) time.sleep(0.5) good_list = bro.find_elements_by_css_selector('li.gl-item') # 循环获取每一个li标签 筛选所需数据 for li in good_list: # 图标标签的src属性 img_tag = li.find_element_by_css_selector('div.p-img a img') img_src = img_tag.get_attribute('src') '''img标签的src属性存在懒加载现象 src没有就在data-lazy-img属性下''' if not img_src: img_src = 'https:' + img_tag.get_attribute('data-lazy-img') # 商品价格 price_tag = li.find_element_by_css_selector('div.p-price strong') order_price = price_tag.text # 商品描述 desc_tag = li.find_element_by_css_selector('div.p-name a em') order_desc = desc_tag.text # 商品链接 link_tag = li.find_element_by_css_selector('div.p-name a') order_link = link_tag.get_attribute('href') # 商品销量 commit_tag = li.find_element_by_css_selector('div.p-commit strong a') order_commit = commit_tag.text # 店铺名称 shop_tag = li.find_element_by_css_selector('div.p-shop span a') shop_name = shop_tag.text # 店铺链接 shop_link = shop_tag.get_attribute('href') # 通过打印展示数据 也可以数据持久化到表格文件 print(""" 商品描述:%s 商品价格:%s 商品图片:%s 商品链接:%s 店铺名称:%s 店铺链接:%s """ % (order_desc, order_price, img_src, order_link, shop_name, shop_link)) bro.close()
多页爬取
大致思路
由于我们使用的是selenuim所以此处只需要查找下一页按钮点击即可
将单页爬取数据的代码封装成一个函数 之后就可以循环爬取多页
知乎登录案例
思路
一、研究发现电脑端知乎不登陆是无法直接访问首页的 二、在network监控中发送登录请求体数据为加密 三、搜索关键字encrypt通过断点调试查看到内部真实数据 四、此时可以研究e这个变量 五、python里调url解析库解个码 六、signature是加密的,得找出它的js加密算法 七、hamc的加密方式,sha-1的加密算法,用python的hmac,hashlib 八、在python里调用node.js去执行,执行js的库叫做 PyExecJS,需要下载 九、node.js中的运行环境和浏览器的运行环境是不一样的,浏览器中会有document,window对象 node.js的运行环境就一个单纯的jsv8引擎,所以需要依赖一个node.js的库jsdom来模拟浏览器环境 十、然后在js代码上面加上一段代码

浙公网安备 33010602011771号