无论什么技术都需要经常的练习,这样才能提高,这次我的目的是爬取汽车之家中芜湖的所有二手车信息并存入数据库。
首先分析汽车之家网站中二手车的信息是利用最基本的get请求获得的,不是利用Ajax请求获得的,因此我们只需要知道每个URL的相同点即可。
分析网页,寻找参数
上面是请求中必须要看的参数,有了这些参数,我们才能进行我们的爬虫。
我们打开网页源代码,按住CTRL+F搜索第一个车的名字,则会显示出如下的界面,这样有利于我们进一步的分析代码。
还有一个关于汽车详细信息的URL也要提取出来。
分析完这个主界面之后,我们就开始分析每个车辆的单独的界面,这样才能提取出更多关于车的信息。
上面的图片中有一个点击查看电话的按钮,这个问题我是想找找它是不是利用Ajax请求获得的,结果找了半天也没找到具体的数据,然后我就采用了另一种方式---利用Selenium获得,我知道这种方式的爬取速度很慢,但是我也没有其他的方法,所以就姑且采用这种技术吧。(有技术的人可以指点一二)
下面还有一些数据,这些数据否是很好获得的
经过这几个界面的分析,大致了解了获得什么数据,然后就是动手写自己的代码了!
开始写代码,获取数据
首先写一个最基本的框架
#获取每一页的URL
def getHtml(url):
try:
headers = {
"Host":"www.che168.com",
"Referer": "https://www.che168.com/huhehaote/list/",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6788.400 QQBrowser/10.3.2864.400",
}
response = requests.get(url,headers = headers)
response.raise_for_status()
response.encoding = response.apparent_encoding
return response.text
except:
return "爬取失败"
这个函数就能获得每一个页面的用源代码了,然后根据我们获取各类数据需求,利用解析库来爬取数据,我习惯利用xpath语法,这种语法我感觉比较简单,而且还很快。具体的代码见最下面。
那个获得卖车人的电话的操作,我利用Selenium模拟点击那个按键,然后从网页源代码中提取出来,这个时候要等待2秒,等电话加载出来才能获取到这个信息,我认为这个操作虽然比较麻烦,但是最终获取到了我们想要的数据。
browser = webdriver.Edge()
browser.implicitly_wait(10)
browser.get(new_href)
button = browser.find_element_by_css_selector(".car-results .btn-iphone3")
# 点击按钮之后,等待两秒钟,然后提取车主的电话
button.click()
time.sleep(2)
# 寻找车主电话
tel = browser.find_element_by_css_selector(".car-results .btn-iphone3")
new_tel = tel.text[1:].strip()
数据存入数据库
这个操作完成之后,我们就可以装入数据库了,我是利用navicat建好数据库之后,然后直接套用数据入库的模板,将数据存入数据库:
def push_data(car_dict):
conn = pymysql.connect(host="localhost", user="root", password="yanzhiguo140710", port=3306, db="qichezhijia")
cur = conn.cursor()
keys = ",".join(car_dict.keys())
values = ",".join(['%s'] * len(car_dict))
sql = "insert into qiche ({keys}) values ({value})".format(keys=keys, value=values)
cur.execute(sql, tuple(car_dict.values()))
conn.commit()
conn.close()
这样这个二手车的数据提取就完成了,我就利用程序跑了半个小时没有什么错误,具体的代码和成果如下:
import requests
from lxml import etree
from selenium import webdriver
import time
import pymysql
#获取每一页的URL
def getHtml(url):
try:
headers = {
"Host":"www.che168.com",
"Referer": "https://www.che168.com/huhehaote/list/",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6788.400 QQBrowser/10.3.2864.400",
}
response = requests.get(url,headers = headers)
response.raise_for_status()
response.encoding = response.apparent_encoding
return response.text
except:
return "爬取失败"
def parse_html(PAGE):
html = etree.HTML(PAGE)
content = html.xpath("//li[@name = 'lazyloadcpc']")
car = {}
for item in content:
# 车的名字
carname = item.xpath("./@carname")[0]
# 二手车的现在售价
price = item.xpath("./@price")[0]
# 二手车的跑的里程数
mile = item.xpath("./@milage")[0]
# 二手车的上户日期
date = item.xpath("./@regdate")[0]
# 二手车的详细信息情况的URL链接
href = item.xpath(".//a[@class = 'carinfo']/@href")[0]
if href.startswith("https"):
new_href = href
else:
new_href = "https://www.che168.com" + href
# 打开详细信息的界面
browser = webdriver.Edge()
browser.implicitly_wait(10)
browser.get(new_href)
button = browser.find_element_by_css_selector(".car-results .btn-iphone3")
# 点击按钮之后,等待两秒钟,然后提取车主的电话
button.click()
time.sleep(2)
# 寻找车主电话
tel = browser.find_element_by_css_selector(".car-results .btn-iphone3")
new_tel = tel.text[1:].strip()
# 用xpath语法会减少时间消耗
new_page = browser.page_source
new_html = etree.HTML(new_page)
# 年检到期
year_cheak = new_html.xpath("//div[@id = 'anchor01']//li/text()")[0].strip()
# 保险到期
insurance = new_html.xpath("//div[@id = 'anchor01']//li/text()")[1].strip()
# 质保到期
quailty = new_html.xpath("//div[@id = 'anchor01']//li/text()")[2].strip()
# 排放标准
emssion = new_html.xpath("//div[@id = 'anchor01']//li/text()")[3].strip()
# 过户次数
guohu1 = new_html.xpath("//div[@id = 'anchor01']//li[5]/span[@class = 'colf8']/text()")[0].strip()
guohu2 = new_html.xpath("//div[@id = 'anchor01']//li/text()")[4].strip()
guohu = guohu1 + guohu2
# 用途
purpose = new_html.xpath("//div[@id = 'anchor01']//li/text()")[5].strip()
# 维修保养
upkeep = new_html.xpath("//div[@id = 'anchor01']//li/text()")[6].strip()
# 车主寄语
# 有可能车主寄语不存在的解决办法
try:
chezhu = browser.find_element_by_css_selector(".infotext-list .businessmen-note .tip-content")
chezhujiyu = chezhu.text
except:
chezhujiyu = "车主寄语不存在"
# #比新车省的钱
try:
cheap_price = new_html.xpath("//div[@class = 'save-money']//div[@class = 'save-money-tb']/text()")[0]
cheap_price = cheap_price[5:].strip()
# #新车含税价
all_price = new_html.xpath("//ul[@id = 'lowPriceCar']//li[1]//span/text()")[0]
# #二手车参考价
refer_price = new_html.xpath("//ul[@id = 'lowPriceCar']//li[2]//span/text()")
if refer_price == []:
refer_price = 0
else:
refer_price = refer_price[0]
except:
cheap_price = "没有这项数据"
all_price = "没有这项数据"
refer_price = "没有这项数据"
# 地址
adder = new_html.xpath("//div[@class = 'car-address']/text()")[0]
adder = adder.replace("地址:", ' ')
adder = adder.strip()
# 联系人
lianxiren = new_html.xpath("//div[@class = 'car-address']/text()")[1]
lianxiren = lianxiren[4:10].strip()
# 发布时间
fabu_time = new_html.xpath("//div[@class = 'car-address']/text()")[1]
fabu_time = fabu_time[-11:-1].strip()
# 发动机
engine = new_html.xpath("//div[@id = 'anchor02']//ul[contains(@class,'infotext-list')]//li[1]/text()")[
0].strip()
# 变速器
speed_change = new_html.xpath("//div[@id = 'anchor02']//ul[contains(@class,'infotext-list')]//li[2]/text()")[
0].strip()
# 车辆级别
car_leavel = new_html.xpath("//div[@id = 'anchor02']//ul[contains(@class,'infotext-list')]//li[3]/text()")[
0].strip()
# 车辆颜色
color = new_html.xpath("//div[@id = 'anchor02']//ul[contains(@class,'infotext-list')]//li[4]/text()")[0].strip()
# 燃油标号
oil = new_html.xpath("//div[@id = 'anchor02']//ul[contains(@class,'infotext-list')]//li[5]/text()")[0].strip()
# 驱动方式
drive = new_html.xpath("//div[@id = 'anchor02']//ul[contains(@class,'infotext-list')]//li[6]/text()")[0].strip()
#将所有的信息存在一个字典里,便于存入数据库
car["carname"] = carname
car["price"] = price
car["mile"] = mile
car["date"] = date
car["new_tel"] = new_tel
car["year_cheak"] = year_cheak
car["insurance"] = insurance
car["quailty"] = quailty
car["emssion"] = emssion
car["guohu"] = guohu
car["upkeep"] = upkeep
car["chezhujiyu"] = chezhujiyu
car["cheap_price"] = cheap_price
car["all_price"] = all_price
car["refer_price"] = refer_price
car["adder"] = adder
car["lianxiren"] = lianxiren
car["fabu_time"] = fabu_time
car["engine"] = engine
car["speed_change"] = speed_change
car["car_leavel"] = car_leavel
car["color"] = color
car["oil"] = oil
car["drive"] = drive
#将数据存入数据库
push_data(car)
#关闭浏览器
browser.close()
#数据进库
def push_data(car_dict):
conn = pymysql.connect(host="localhost", user="root", password="yanzhiguo140710", port=3306, db="qichezhijia")
cur = conn.cursor()
keys = ",".join(car_dict.keys())
values = ",".join(['%s'] * len(car_dict))
sql = "insert into qiche ({keys}) values ({value})".format(keys=keys, value=values)
cur.execute(sql, tuple(car_dict.values()))
conn.commit()
conn.close()
if __name__ == '__main__':
first_url = "https://www.che168.com/hefei/a0_0msdgscncgpi1ltocsp1ex/"
page = getHtml(first_url)
parse_html(page)
for i in range(2,100):
try:
url = "https://www.che168.com/hefei/a0_0msdgscncgpi1ltocsp"+str(i)+"exx0/"
page = getHtml(url)
parse_html(page)
except:
print("数据已经爬取完毕")
还有一张数据在数据库中截图:
这样就算完成了这个小小的目标,接下来就是分析这些数据,具体的分析方法和数据可视化我正在学。
有兴趣的小伙伴可以一起交流啊!