爬虫案例:汽车用户消费投诉数据爬取
任务:爬取某公开网站上的汽车用户消费投诉数据('http://tousu.315che.com/tousulist/serial/55467/'),字段包含品牌、投诉内容、品牌车型、单号、投诉问题、投诉时间和经销商,并为完成后续项目做准备。
(1)获取所有品牌名称、链接
(思路:首先向网页发送请求、解析网页,可利用xpath或者beautifulsoup中的find、find_all方法进行品牌名称、链接的提取。)
#(1)获取所有品牌名称、链接
import requests
from lxml import etree
url = 'http://tousu.315che.com/tousulist/serial/55467/'
#发送请求
rq = requests.get(url)
rq.text #获取到的内容是乱码的
rq.encoding = 'UTF-8' #设置编码
#网页解析
html = etree.HTML(rq.text)
#提取数据
brand_name = html.xpath('//*[@id="letterTabList"]/div/a/text()') #品牌名称
brand_link = html.xpath('//*[@id="letterTabList"]/div/a/@href') #品牌链接
#剔除非网址数据
print('处理前的品牌数量为:',len(brand_name), ',品牌链接数量为:',len(brand_link))
ind = brand_link.index('javascript:;') #得到非网址数据所对应的索引位置
del brand_link[ind] #索引回原始数据进行删除
del brand_name[ind]
print('处理后的品牌数量为:',len(brand_name), ',品牌链接数量为:',len(brand_link))
(2)进入单个品牌的界面,爬取其全部投诉的页面网址
(思路:单个品牌可能只有一页的投诉网址,那么直接对该投诉网址发送请求、解析网页、提取数据即可。但是,单个品牌有些有多页的投诉网址,如大众。这时需要找到多页投诉网址间的规律,这其中肯定是需要知道该品牌投诉网址的总页数。投诉网址的总页数可通过投诉宗数除以9得到(因为一个页面只呈现9个投诉网址)。那么各投诉网址之后就可以利用for循环分别发送请求、解析网页、提取数据。如果要对多个品牌进行操作的话,则在外层写for循环即可,循环每一个品牌链接。。同样的,提取到的数据需要全部汇总在一起。)
#①获取第一个品牌的第一页投诉网址中的投诉详情链接
#发送请求
rq1 = requests.get(brand_link[0])
rq1.text
rq1.encoding = 'UTF-8' #设置编码
#网页解析
html1 = etree.HTML(rq1.text)
#提取数据
tousu_link = html1.xpath('/html/body/div[1]/div[2]/div[2]/div[1]/div[2]/div[2]/ul/li/a/@href') #投诉链接
brand_link[0]这个链接下面的“Artega”品牌刚好只有1页的投诉链接,所以这个品牌的投诉链接都爬取完成。
但是像大众这个品牌下是有很多页的投诉链接。所以这时需要找到多页投诉网址间的规律,这其中肯定是需要知道该品牌投诉网址的总页数。投诉网址的总页数可通过投诉宗数除以9得到(因为一个页面只呈现9个投诉网址)。那么各投诉网址之后就可以利用for循环分别发送请求、解析网页、提取数据。
#②获取大众品牌(有多页投诉网址)的投诉详情链接
import math
#发送请求
rq1 = requests.get('http://tousu.315che.com/tousulist/serial/93/')
rq1.text #乱码
rq1.encoding = 'UTF-8' #设置编码
#网页解析
html1 = etree.HTML(rq1.text)
#提取数据
counts = html1.xpath('/html/body/div[1]/div[2]/div[2]/div[1]/div[2]/div[1]/span/em/text()') #投诉宗数
pages = math.ceil(int(counts[0])/9) #math.ceil表向上取整,即小数部分直接舍去,并向正数部分进1
# http://tousu.315che.com/tousulist/serial/93/0/0/0/1.htm
# http://tousu.315che.com/tousulist/serial/93/0/0/0/2.htm
# http://tousu.315che.com/tousulist/serial/93/0/0/0/3.htm
urls = [] #构建空列表存放当前品牌的投诉网址
for j in range(1, pages+1):
u = 'http://tousu.315che.com/tousulist/serial/93/' + '0/0/0/' + str(j) +'.htm'
urls.append(u)
all_tousu_link = [] #构建空列表存放全部投诉链接
for k in urls[:5]: #此处演示只爬取前5个投诉网址
#发送请求
rq2 = requests.get(k)
rq2.encoding = 'UTF-8'
#解析网页
html2 = etree.HTML(rq2.text)
#提取数据
tousu_link = html2.xpath('/html/body/div[1]/div[2]/div[2]/div[1]/div[2]/div[2]/ul/li/a/@href') #投诉链接
all_tousu_link.extend(tousu_link)
append和extend的区别
list1 = ['a','b']
list2 = ['c','d']
list1.append(list2) #整个列表追加到列表后面
list1.extend(list2) #一个一个元素追加到列表后面
任务(2)完整的爬取过程如下,其实就是在上面”大众“品牌代码的基础上写一个for循坏爬取每个品牌的投诉链接。
#全部品牌的投诉链接爬取
import math
all_tousu_link = [] #构建空列表存放全部投诉链接
for i in range(0, 5): #如果要爬取多页的话,更改”5“这个数值即可
print('正在爬取' + brand_name[i] +'品牌')
#发送请求
rq1 = requests.get(brand_link[i])
rq1.text #乱码
rq1.encoding = 'UTF-8' #设置编码
#网页解析
html1 = etree.HTML(rq1.text)
#提取数据
counts = html1.xpath('/html/body/div[1]/div[2]/div[2]/div[1]/div[2]/div[1]/span/em/text()') #投诉宗数
pages = math.ceil(int(counts[0])/9) #投诉总页数。math.ceil表向上取整,即小数部分直接舍去,并向正数部分进1
urls = [] #构建空列表存放当前品牌的投诉网址
for j in range(1, pages+1):
u = brand_link[i] + '0/0/0/' + str(j) +'.htm'
urls.append(u)
for k in urls:
#发送请求
rq2 = requests.get(k)
rq2.encoding = 'UTF-8'
#解析网页
html2 = etree.HTML(rq2.text)
#提取数据
tousu_link = html2.xpath('/html/body/div[1]/div[2]/div[2]/div[1]/div[2]/div[2]/ul/li/a/@href') #投诉链接
#存储数据
all_tousu_link.extend(tousu_link)
(3)循环所有投诉页面,爬取其中的数据(品牌、投诉内容、品牌车型、单号、投诉问题、投诉时间和经销商)
思路:循环每个投诉页面网址,发送请求、解析网页、提取数据、保存数据。
更多推荐
所有评论(0)