本教程是在学习python爬虫第一个比较完整的记录(针对和我一样的萌新人群)。
1.需要的包
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import csv
具体如何安装包这里不在阐述
这里对用到的包做一个简单的介绍:
BeautifulSoup:提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据。
selenium :是一个用于Web应用程序测试的工具,(后续还会出一个使用requests的教程)
time:有关于输出时间返回时间,以及控制延迟执行程序的一些作用
csv:一个python自带的标准库,可以实现后面把数据写入csv文件内,便于阅读
2.简单的分析网站的网址结构以及请求方式
这次主要目标是爬取jd的搜索出来的商品信息,所以我们就拿jd的搜索举例子:
首先我们先打开这个网址,可以看到是京东的主页,然后我们在搜索栏里输入一个商品名称,例如5700然后点击跳转
你会发现这个网址变成了这个样子
https://search.jd.com/Search?keyword=5700&enc=utf-8&wq=5700&pvid=ef71ad5b505642529ec048d0e46e7e40
我们对这个网址进行简单的分析一下
keyword:很简单的关键词
enc:也很简单是个字符的编码方式
至于wq,pvid可以暂时不用去理他这样我们得到了一个最简单的搜索网址
https://search.jd.com/Search?keyword=5700&enc=utf-8
然后我们可以访问一下这个网址,是不是出现了和刚才一摸一样的界面
然后我们进入第二步
jd的网页稍微有点特殊的是,他在搜索栏目得到数据的时候,总共获取到的是60个数据但是刚开始的时候她只会显示三十个数据,后面的三十个商品信息是通过浏览器下滑的时候实现动态的加载。这里我稍微提一下后面会用selenium 来解决这个问题
我们看到最下面的的目录栏,先点击一下一然后看地址栏中的信息
https://search.jd.com/Search?keyword=5700&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&page=1&s=1&click=0
然后点击第二页的
https://search.jd.com/Search?keyword=5700&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&page=3&s=61&click=0
接下来是第三页的信息
https://search.jd.com/Search?keyword=5700&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&page=5&s=121&click=0
我们来对比一下三个网址的区别在哪
其实三个网址主要变化的是倒数第二个参数和第三个参数
page很容易理解就是第几页的意思,至于第一页是1第二页是3我们可以用一个表达式来完成就是2*page-1
至于后面的s瞎猜一下因该是商品的取值区间
然后根据这个我们来构建我们请求网页时候的url了
urlBase+'keyword='+wd+'&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&page='+str(2*page-1)
到此为止,后面部分请求的url就已经构造完成了。
3.使用selenium进行自动化操作(还有一篇使用request)
#启动chrome
driver = webdriver.Chrome()
#导航到目标网址
driver.get(url)
#执行js脚本
driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
#延迟时间五秒,防止其他原因没有完全加载完页面
time.sleep(5)
#最后拿到我们需要的页面数据
driver.page_source
注意:这里需要注意的几个点
你用的浏览器是啥启动那个浏览器就用啥,这里用chrome其他自行百度
在启动浏览器的时候应该会出现没有驱动的错误,这里不多阐述,这个作者汇总了所有的驱动包可以去看看
https://blog.youkuaiyun.com/vicky_lov/article/details/83344708
然后这个是具体的操作步骤
https://blog.youkuaiyun.com/weixin_37185329/article/details/80493281
https://www.jianshu.com/p/dc0336a0bf50
4.获取到网页的元素之后我们需要做的就是处理网页的数据来获取我们需要的数据
这里我们用的是bs4来解析网页的数据
在此之前我需要去仔细翻看一下jd网页的网页结构,
可见每一个商品都是一个单独的li里面的信息,由他的class命名方式可以明显猜出他的含义。
#使用lxml的方式来解析html的源文件
soup = BeautifulSoup(html_data, 'lxml')
#查找所有class为gl-item的li标签
lis = soup.find_all('li', class_='gl-item')
#用来做最终的数据储存
goods_data = []
for i in range(len(lis)):
try:
# 获取商品名称信息
name = lis[i].find('div', class_='p-name').a['title']
# 获取商品信息 div 中的第一个 a 标签, 获取 title 属性值
title = lis[i].a['title']
# 获取商品的价格信息
price = lis[i].find('div', class_="p-price").i.string
#获取店家信息
shop = lis[i].find('div', class_="p-shop").a['title']
#获取图片地址
img = lis[i].find('div', class_="p-img").div['style']
goods_data.append([name, price, shop, img])
except:
print('error')
5.在获取到数据之后我们需要将他存入文件中方便阅读
这里我们用的是csv,一个python自带的控制文件
具体的文件写入可以参考这位的
https://blog.youkuaiyun.com/weixin_36279318/article/details/79078255
的资料,什么形式的打开方式都有描述到
#以a的形式打开目标地址的文件,如果没有就先创建
with open("D:\\test.csv", "a") as csv_file:
write = csv.writer(csv_file)
print(goods_data[1])
#循环写入文件数据
for i in range(len(goods_data)):
write.writerow(goods_data[i])
最后放上全部的代码:
from bs4 import BeautifulSoup
from selenium import webdriver
import time
import csv
def getUrl():
urlBase = 'https://search.jd.com/Search?'
wd = input('请输入所需要获取的商品名称')
pageMax = 2*int(input('请输入需要爬取的页数'))-1
url = urlBase+'keyword='+wd+'&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&page='+str(pageMax)
return url
def getdata(url):
driver = webdriver.Chrome()
driver.get(url)
driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
time.sleep(5)
return driver.page_source
def dealWithData(html_data):
soup = BeautifulSoup(html_data, 'lxml')
lis = soup.find_all('li', class_='gl-item')
goods_data = []
for i in range(len(lis)):
try:
name = lis[i].find('div', class_='p-name').a['title']
title = lis[i].a['title']
price = lis[i].find('div', class_="p-price").i.string
shop = lis[i].find('div', class_="p-shop").a['title']
img = lis[i].find('div', class_="p-img").div['style']
goods_data.append([name, price, shop, img])
except:
print('')
with open("D:\\test.csv", "a") as csv_file:
write = csv.writer(csv_file)
print(goods_data[1])
for i in range(len(goods_data)):
write.writerow(goods_data[i])
def main():
url = getUrl()
html_data = getdata(url)
dealWithData(html_data)
main()
最后总结一下,这简单的爬虫还是蛮好玩的,但是缺少点东西始终觉得,国内大佬的巨作哈哈哈,其实最开心的就是看到在走前辈路的同时看到世界上的形形色色,忽然看到前辈大佬的,哇,就像在学vue的时候,莫名的感觉,哈哈哈哈好像跑远了
忘记最后说一下了,测试的时候不要一次性跑几十张页面的获取,容易被拉黑名单以及封ip,务必自己把握分寸!