昨日内容回顾
-
京东多页及函数封装
1.多页思路 研究url规律 直接查找下一页链接 2.代码封装 什么是函数 函数的作用 为什么封装
-
openpyxl模块
pandas模块 内部封装了openpyxl pd.read_excel() pd.read_csv() openpyxl模块 WorkBook load_workbook xlrd与xlwt模块 百度查找相应文档 excel版本问题 .xls .xlsx 1.创建excel文件及工作簿 2.写入数据 3.读取数据
-
利用openpyxl保存商品数据
今日内容概要
- 商品数据爬取与存储
- 电影数据爬取与存储
- 贴吧图片爬取与存储
- 补充防爬措施及解决策略
- 大型网络爬虫实战案例(防爬措施很复杂 解决措施也复杂)
今日内容详细
商品数据爬取与存储
from selenium import webdriver
import time
from selenium.webdriver.common.keys import Keys
from openpyxl import Workbook
# excel文件相关
wb = Workbook()
w1 = wb.create_sheet('商品数据',0)
# 先定义表头
w1.append(['序号','商品链接','商品图片','商品简介','商品价格','商品销量'])
count = 1
def get_goods(bro):
# 先查找所有的li标签
li_list = bro.find_elements_by_class_name('gl-item')
"""
注意 bro.find_element有加不加s之分
不加s表示查找单个元素
加s表示查找所有元素
"""
global count # 引用全部变量count
for li in li_list:
img = li.find_element_by_css_selector('.p-img a img')
'''图片的路径有时候在src中有时候在data-lazy-img中'''
img_src = img.get_attribute('src')
if not img_src:
img_src = 'https:' + img.get_attribute('data-lazy-img')
# 商品图片
link = li.find_element_by_css_selector('.p-img a').get_attribute('href')
# 商品链接
price = li.find_element_by_css_selector('.p-price i').text
# 商品价格
name = li.find_element_by_css_selector('.p-name em').text.replace('\n', '')
# 商品名称
comment = li.find_element_by_css_selector('.p-commit a').text
# 商品简介
w1.append([count,link,img_src,name,price,comment])
count += 1
# for结束表示一页数据爬取结束 可以开始下一页了
next_page = bro.find_element_by_partial_link_text('下一页')
time.sleep(1)
# 点击下一页
next_page.click()
# 再次爬取数据
time.sleep(1)
get_goods(bro)
# 控制谷歌浏览器
bro=webdriver.Chrome()
# 明确目标网站和请求方式
bro.get("http://www.jd.com")
bro.implicitly_wait(10)
# 获取用户想要搜索的商品名称
targetGood = input('请输入您想要爬取的商品名称>>>:').strip()
# targetGood = '显卡' # 先固定写法 方便测试
# 查找商品搜索款 填写内容
btnEle = bro.find_element_by_id('key')
btnEle.send_keys(targetGood)
btnEle.send_keys(Keys.ENTER)
# 进入了另一个页面
try:
get_goods(bro)
except Exception as e:
print("结束", e)
finally: # try检测的代码运行完毕之后无论是否有报错 都会执行finally代码块
wb.save('%s数据.xlsx'%targetGood)
bro.close()
电影数据爬取与存储
当不是很熟练的情况下爬取数据最后遵循以下思路
1.先研究一页数据的爬取
2.再考虑多页数据的爬取
https://movie.douban.com/top250
https://movie.douban.com/top250?start=25&filter=
https://movie.douban.com/top250?start=50&filter=
https://movie.douban.com/top250?start=75&filter=
3.最后研究保存策略
在爬取模块的选择方面 先考虑使用最基本的requests 简单的网站基本都够用
"""
豆瓣防爬
1.需要校验User-Agent参数
2.还会限制ip访问次数
time.sleep()
"""
import requests
from bs4 import BeautifulSoup
import time
from openpyxl import Workbook
import re
# 存入文件函数
def get_file():
wb = Workbook()
w1 = wb.create_sheet('电影排行数据',0)
# 添加表头
w1.append(['电影名称','导演','主演','年代','地区','类型','电影评分','电影评价','电影标语'])
return wb,w1
# 获取数据函数
def get_data(base_url,w1):
# 直接朝地址发请求
res = requests.get(base_url,
# 返回状态码418说明请求不合法 需要研究防爬措施 先加User-Agent参数
headers={
"User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
}
)
# 筛选数据
soup = BeautifulSoup(res.text, 'lxml')
# 获取包裹电影信息的li标签列表
li_list = soup.select('ol.grid_view li')
# for循环获取数据
for li in li_list:
title = li.select('.hd a>.title')[0].text
desc = li.select('.bd p')[0].text.strip()
rating_num = li.select('.star>.rating_num')[0].text
comment = li.select('.star span')[-1].text
quote = li.select('.quote span')[0].text if li.select('.quote span') else '暂无标语'
print("""
电影名称:%s
电影简介:%s
电影评分:%s
电影评价:%s
电影标语:%s
""" % (title, desc, rating_num, comment, quote))
"""数据筛选思路如下
import re
res = '导演: 王家卫 Kar Wai Wong 主演: 张国荣 Leslie Cheung / 梁朝伟 Tony Leu...
1997 / 中国香港 日本 韩国 / 剧情 爱情 同性'
# 思路一:使用split与strip组合使用
# print(res.split(':')[-1].split('...'))
# 思路二:使用正则
print(re.findall('导演: (.*)主演',res)[0].strip())
print(re.findall(r'主演: (.*)...',res)[0].strip())
print(re.findall('\d+',res)[0].strip())
print(re.findall(r'/(.*?)/',res)[0].strip())
print(re.findall('/.*?/(.*)',res)[0].strip())
"""
# 换页函数
def get_page(w1):
for i in range(0,250,25):
base_url = "https://movie.douban.com/top250?start=%s&filter="%i
get_data(base_url,w1)
time.sleep(1)
# 启动函数
def get_start():
wb,w1 = get_file()
get_page(w1)
wb.save('电影Top250.xlsx')
get_start()
爬取贴吧图片数据
"""
知识储备
os模块
import os
# 判断当前文件路径是否存在
print(os.path.exists(r'D:\数据分析五期\pa_day08'))
# 创建文件夹
os.mkdir('代码创建的')
"""
用户指定任意的贴吧名称 我们抓取内部所有的图片数据并保存到本地
研究地址
https://tieba.baidu.com/f?kw=%E4%B8%83%E9%BE%99%E7%8F%A0
https://tieba.baidu.com/f?kw=%E6%A0%A1%E8%8A%B1
https://tieba.baidu.com/f?kw=python
不同的贴吧仅仅是后缀不一样通过kw控制具体贴吧名称
requests.get(url,params={'kw':'七龙珠'})
针对分页数据也可以让用户自定义爬取页码
输入起始页 输入终止页
拼接url即可
import requests
import os
from lxml import etree
base_url = 'https://tieba.baidu.com/f'
# 获取用户需要爬取的贴吧名称
# targetUrl = input('请输入您需要爬取的贴吧名称>>>:').strip()
# 为了测试方便我们先写死
targetUrl = '七龙珠'
if not os.path.exists(targetUrl):
os.mkdir(targetUrl)
# 切换到校花路径下
os.chdir(targetUrl)
proxies={
'http':'112.123.219.168:9999',
'http':'117.29.242.174:8080',
'http':'171.208.21.145:8080',
'http':'112.194.90.29:8888'
}
# 构造完成的贴吧路径发送请求
res = requests.get(base_url,params={'kw':targetUrl},
proxies=proxies,
headers={
"User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
}
)
res.encoding = 'utf8'
print(res.text)
xp = etree.HTML(res.text)
# 筛选所有的贴子链接
link_list = xp.xpath("//a[@class='j_th_tit ']/@href")
# for循环拼接完整路径
for i in link_list:
full_url = 'https://tieba.baidu.com' + i
# 二次请求
print(full_url)
res1 = requests.get(full_url,proxies=proxies,headers={
"User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
})
xp1 = etree.HTML(res1.text)
# 查找页面所有的img标签的src属性
src_list = xp1.xpath("//img[@class='BDE_Image']/@src")
# for循环访问图片数据并写入文件中
for src in src_list:
res2 = requests.get(src,proxies=proxies,headers={
"User-Agent": "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
})
# 拼接图片文件的完整路径
# 利用文件操作w模式自动创建并写二进制数据
# print(src)
print(src[-10:])
# with open(src[-10:0],'wb') as f:
# f.write(res2.content)
"""
ip代理池
"""
作业
1.独立完成豆瓣数据爬取 并尝试着从详情页中爬取更多的数据
基本要求是针对电影简介做数据拆分
拔高爬取详情页更多数据(尝试即可 注意访问频率)
2.独立完成贴吧数据爬取 参考课堂代码及tests文件代码
不要做任何的封装先实现功能
之后考虑封装
再考虑分页(贴吧主页面分页)