实战
1.需求
招商银行信用卡积分兑换商城:https://www.51credit.com/jifen/zhaoshang/p1/
爬取招商银行信用卡积分兑换商城中的商品名称和商品分类。
2.浏览器检查网页
输入网址进入网页后,点按F12或者鼠标右键-检查,即可看到一大堆代码,也就是网页的HTML。在HTML中可以找到商品的信息:
也可以鼠标右键-查看页面源代码查看网页的HTML。可以直接在页面源代码HTML中找到数据的网页是静态网页,找不到的就是动态网页
静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非你修改页面代码。而动态网页则不然,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。
静态网页的爬取数据相对简单点,获取到网页的HTML,从HTML中解析到自己想要的数据,然后保存即可。
3.requests库获取HTML数据
使用requests.get()方法获取网页的HTML:
import requests
url = 'https://www.51credit.com/jifen/zhaoshang/p1/'
req = requests.get(url)
html = req.text
print(html)
requests.get()方法必须设置的一个参数就是url,因为我们得告诉GET请求,我们的目标是谁,我们要获取谁的信息。运行结果为:
可以看出,我们已经获取了网页的HTML,接下来就是从HTML中解析出商品的数据了。
3.Beautiful Soup库解析HTML数据
F12进入检查,从HTML中查找商品的数据,可以发现所有的商品数据都存放在标签<ul class="list_pro clearfix">
中 点击这个标签,发现所有的商品都被涵盖变蓝
使用以下代码获取标签<ul class="list_pro clearfix">
中的数据:
import requests
from bs4 import BeautifulSoup
url = 'https://www.51credit.com/jifen/zhaoshang/p1/'
req = requests.get(url)
html = req.text
bf = BeautifulSoup(html)
#获取标签<ul class="list_pro clearfix">中的内容
ul_data = bf.find_all('ul', class_ = 'list_pro clearfix')
print(ul_data)
find()返回的是第一个匹配的标签结果,find_all()方法返回的是所有匹配结果的列表 find_all中传入的第一个参数为标签元素类别如ul,后面的class_中就是class属性中的内容
运行结果为:
运行结果中已经可以看到商品的名称和类别信息了,当然这还不够,我们还需把数据继续解析出来。
继续查看HTML代码:
商品类别在<li>
标签下的<p class="c6">
标签中,商品名称在<li>
标签下的<h4>
标签中。
正所谓由浅入深,我们先试着把第一个商品的数据解析出来:
import requests
from bs4 import BeautifulSoup
url = 'https://www.51credit.com/jifen/zhaoshang/p1/'
req = requests.get(url)
html = req.text
bf = BeautifulSoup(html)
#获取标签<ul class="list_pro clearfix">中的内容
ul_data = bf.find_all('ul', class_ = 'list_pro clearfix')
c6_data = ul_data[0].find_all('p',class_ = 'c6')
c6 = c6_data[0].find_all('a')
print(c6[1].string)
h4_data = ul_data[0].find_all('h4')
h4 = h4_data[0].find_all('a')
print(h4[0]['title'])
代码解析:
(1)ul_data[0],c6_data[0],h4_data[0]:find_all()方法返回的是所有匹配结果的列表,而[0]则是列表中的第一个元素。
(2)c6[1].string:<p class="c6">标签下有两个<a href标签,find_all()方法返回的列表有两个,商品在第二个元素,所以为c6[1],.string返回<a href标签中的内容:
(3)h4[0][‘title’]:返回title=的内容:
第一个商品数据爬取出来了,剩余商品自然不成问题,加几个循环即可:
import requests
from bs4 import BeautifulSoup
url = 'https://www.51credit.com/jifen/zhaoshang/p1/'
req = requests.get(url)
html = req.text
bf = BeautifulSoup(html)
#获取标签<ul class="list_pro clearfix">中的内容
ul_data = bf.find_all('ul', class_ = 'list_pro clearfix')
for i in ul_data[0].find_all('li'):
c6_data = i.find_all('p',class_ = 'c6')
h4_data = i.find_all('h4')
for h4 in h4_data[0].find_all('a'): #获取title值,即商品名称
goods = h4['title']
for c6 in c6_data[0].find_all('a')[1]: # 返回一个列表,获取第二个值,即商品类型
types = c6.string
print(goods)
print(types)
运行结果:
4.写入CSV文件
import csv
import requests
from bs4 import BeautifulSoup
url = 'https://www.51credit.com/jifen/zhaoshang/p1/'
req = requests.get(url)
html = req.text
bf = BeautifulSoup(html)
commodity_data = []
#获取标签<ul class="list_pro clearfix">中的内容
ul_data = bf.find_all('ul', class_ = 'list_pro clearfix')
for i in ul_data[0].find_all('li'):
c6_data = i.find_all('p',class_ = 'c6')
h4_data = i.find_all('h4')
for h4 in h4_data[0].find_all('a'): #获取title值,即商品名称
goods = h4['title']
for c6 in c6_data[0].find_all('a')[1]: # 返回一个列表,获取第二个值,即商品类型
types = c6.string
commodity_data.append([goods]+[types]) #将商品和类型组合成一个数组,否则写入CSV文件时列不对应
# print(commodity_data)
title = ["商品名称","商品类别"]
with open('F:\commodity-data.csv', 'a+', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(title)
for row in commodity_data:
writer.writerow(row)
print('save complete')
保存结果:
至此,爬取第一页的商品数据已经完成了,下面附上爬取全部商品(包括商品详情数据)的代码
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 12 14:46:17 2021
@author: Wingkin
"""
import csv
import requests
from bs4 import BeautifulSoup
#爬取的网址:https://www.51credit.com/jifen/zhaoshang/p1/
def get_data(url):
req = requests.get(url)
html = req.text
bf = BeautifulSoup(html)
#获取标签<ul class="list_pro clearfix">中的内容
ul_data = bf.find_all('ul', class_ = 'list_pro clearfix')
commodity_data = []
for i in ul_data[0].find_all('li'):
#获取<p class="c6">和<h4>中的内容
c6_data = i.find_all('p',class_ = 'c6')
h4_data = i.find_all('h4')
for h4 in h4_data[0].find_all('a'): #获取title值,即商品名称
goods = h4['title']
detail_url = h4['href']
detail_req = requests.get('https://www.51credit.com'+detail_url)
detail_bf = BeautifulSoup(detail_req.text)
div_data = detail_bf.find_all('div', class_ = 'pro_detail')
for a in div_data[0].find_all('p'):
product_details = a.string
for c6 in c6_data[0].find_all('a')[1]: # 返回一个列表,获取第二个值,即商品类型
types = c6.string
commodity_data.append([goods]+[types]+[product_details]) #将商品和类型组合成一个数组,否则写入CSV文件时列不对应
return commodity_data
def save_title_to_csv(file_name,title):
with open(file_name, 'a+', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(title)
def save_data_to_csv(file_name,data):
with open(file_name, 'a+', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
for row in data:
writer.writerow(row)
if __name__ == '__main__':
file_name = 'F:\实习\爬虫\commodity_data_detail1.csv'
title = ["商品名称","商品类别","商品详情"]
save_title_to_csv(file_name,title)
#爬取50页数据
for url_id in range(1,51):
target = 'https://www.51credit.com/jifen/zhaoshang/p'+str(url_id)+'/'
save_data_to_csv(file_name,get_data(target))
print('爬取url数据:'+target)
if(url_id == 50):
print('爬取完成')