代码拉取完成,页面将自动刷新
"""
汽车之家多级页面爬取,爬取汽车:型号、行驶里程、上牌时间、档位、排量、所在地、价格
url:https://www.che168.com/china/a0_0msdgscncgpi1lto1cspexx0/#pvareaid=108343 :第一页
https://www.che168.com/china/a0_0msdgscncgpi1lto1csp2exx0/?pvareaid=102179#currengpostion :第二页
https://www.che168.com/china/a0_0msdgscncgpi1lto1csp{n}exx0/?pvareaid=102179#currengpostion :第n页
一级正则:<li class="cards-li list-photo-li ".*?<a href="(.*?)".*?</li>
二级正则: <div class="car-box">.*?<h3 class="car-brand-name">(.*?).*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<span class="price" id="overlayPrice">(.*?)</b>.*?</div>
增量爬虫
"""
from urllib import request
import re
import time
import random
import pymysql
from hashlib import md5
import sys
class CarHomeSpider:
def __init__(self):
self.url = 'https://www.che168.com/china/a0_0msdgscncgpi1lto1csp{}exx0/?pvareaid=102179#currengpostion'
self.headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'}
# 计数
self.count = 0
# 连接数据库
self.db = pymysql.connect(host='localhost', user='root', password='123456', database='cardb', charset='utf8')
self.cursor = self.db.cursor()
def get_html(self, url):
"""获取响应内容"""
req = request.Request(url=url, headers=self.headers)
res = request.urlopen(req)
# ignore 遇到不能识别的字符,忽略掉,不抛出异常 gb2312通过查看网页源码看charset内容获取,和网站保存一致,否则会报错,或者卡住
html = res.read().decode(encoding='gb2312', errors='ignore')
return html
def re_func(self, regex, html):
"""解析提取数据"""
# print(html)
pattern = re.compile(regex, re.S)
r_list = pattern.findall(html)
print(r_list)
return r_list
def parse_html(self, one_url):
"""数据抓取函数"""
one_html = self.get_html(one_url)
one_regex = '<li class="cards-li list-photo-li ".*?<a href="(.*?)".*?</li>'
# href_list : ['/declear/xxxx'] 这个需要拼接 在前面加上主域名
href_list = self.re_func(one_regex, one_html)
# print(href_list)
for href in href_list:
# 拼接详情页链接
car_url = 'https://www.che168.com' + href
# 判断是否抓取过
url_md5 = self.md5_url(car_url)
sel = 'select * from request_finger where finger=%s'
self.cursor.execute(sel,[url_md5])
result = self.cursor.fetchall()
# result 为空,标识之前未抓取过
if not result:
self.get_data(car_url)
# 控制抓取时间 time.sleep(random.uniform(0, 1)) uniform生成一个指定范围的浮点数
time.sleep(random.randint(1, 3))
# 存入指纹表
ins = 'insert into request_finger values(%s)'
self.cursor.execute(ins,[url_md5])
self.db.commit()
else:
sys.exit('抓取完成')
def get_data(self, car_url):
"""抓取1辆汽车详情页数据"""
print(car_url)
two_html = self.get_html(car_url)
# two_regex = '<div class="car-box">.*?<h3 class="car-brand-name">(.*?)</h3>.*?<ul class="brand-unit-item fn-clear">.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<span class="price" id="overlayPrice">¥(.*?).*?</div>'
# car_list : [(a,b,c,d),()] 下面two_regex中¥加上后,匹配不到网页内容,但是不加,匹配的价格异常
# two_regex = '<div class="car-box">.*?<h3 class="car-brand-name">(.*?)</h3>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<span class="price" id="overlayPrice">¥(.*?)<b>万</b><i class="usedfont used-xiajiantou"></i>.*?'
two_regex = '<div class="car-box">.*?<h3 class="car-brand-name">(.*?)</h3>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<h4>(.*?)</h4>.*?<span class="price" id="overlayPrice">(.*?)<b>.*?</b>.*?</div>'
# print(two_regex)
# print(two_html)
car_list = self.re_func(two_regex, two_html)
if len(car_list) == 0:
print('car_list 为空')
return
item = {}
# 汽车名
item['name'] = car_list[0][0].strip()
# 行驶里程
item['km'] = car_list[0][1].strip()
# 上牌时间
item['time'] = car_list[0][2].strip()
# 类型
item['type'] = car_list[0][3].split('/')[0].strip()
# 排量
item['displace'] = car_list[0][3].split('/')[1].strip()
# 所在地
item['city'] = car_list[0][4].strip()
# 价格 匹配的内容为[¥价格值]eg:¥156 156万
item['price'] = car_list[0][5].split(';')[1].strip()
ins = 'insert into cartab values(%s,%s,%s,%s,%s,%s,%s)'
# 这里在pycharm中有快捷键,按住alt键,可以向ctrl一样的作用,哪怕每行长短不一致
li = [
# 汽车名
item['name'],
# 行驶里程
item['km'],
# 上牌时间
item['time'],
# 类型
item['type'],
# 排量
item['displace'],
# 所在地
item['city'],
# 价格 匹配的内容为[¥价格值]eg:¥156 156万
item['price'],
]
self.cursor.execute(ins, li)
self.db.commit()
print(item)
self.count+=1
def save_html(self, r_list):
"""数据处理函数"""
for r in r_list:
# r[0] 为元组的第一个元素,strip()函数作用是去掉字符串两边的空格
# 一行一行写入---start
car_info = []
for info in r:
car_info.append(info.strip())
self.csvWriter.writerow(car_info)
self.moveCount += 1
print(car_info)
# 一行一行写入-----end
def md5_url(self, url):
"""对url地址进行md5加密"""
s = md5()
s.update(url.encode())
return s.hexdigest()
def run(self):
"""程序入口函数"""
for offset in range(1, 2, 1):
url = self.url.format(offset)
self.parse_html(url)
# 控制抓取时间
# time.sleep(random.randint(1, 3))
# 断开数据库
self.cursor.close()
self.db.close()
if __name__ == '__main__':
spider = CarHomeSpider()
spider.run()
print('汽车数量为%d' % spider.count)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。