您的当前位置:首页>新品 > 正文

如何用网页爬取数据?数据爬取技巧-天天播资讯

来源:CSDN 时间:2022-12-29 09:30:15

一、抓取数据

1、抓取数据的意义

对电商来说,抓取某些数据,再进行分析,可以有效地反映出数据在某个区间内变化情况。数据受某些因素而发生巨大的影响,也可以借助分析的数据来规划相关项目的后续发展。因此,如果能利用网页爬取数据技术获取数据并对各种数据进行统计分析,对后续淘宝的发展具有指导意义。


(资料图片)

2、抓取的内容

包括:商品名称title、商品价格price、付款人数deal,店铺名称shop、店铺地址location、商品的详情页detail_url。

3、实现内容

1、开打淘宝网站,输入搜索内容“word”查找商品

2、再解决登录问题(登录时解决网站对selenium的判别,修改浏览器的内部属性,否则被识别出有selenium,需要进行滑动登陆验证。但是在运行时,你手动地去进行滑动登录也是会判别出存在selenium的,进而登陆不上去)

3、对查找商品在控制台上输出

4、具体实现代码

4.1所需模块

from selenium import webdriverimport timeimport random

首先的话,我们需要导入一些模块,比如第三方模块selenium,大家如果发生报错的话,就需要额外安装了,安装selenium模块有2个方法:

1、在pycharm的terminal控制台命令行中输入:pip install selenium

2、在win+r中的cmd里输入:pip install selenium

这两个方法都是可以的。

import timeimport random

这两个的话,我们则是用来设置随机时间的,在抓取到数据之前,我们需要点击搜索框、搜索一些按键。我们需要模拟人为的操作时间,否则的话很可能操作失败了,我们随机地等待1-3秒的时间。

4.2创建chrome浏览器,打开淘宝网

在关于创建浏览器的话,首选是chrome浏览器,调出开发者模式太方便了!!!,火狐也是可以的,但首选首选首选chrome,因为我真的没用过火狐,哈哈哈哈哈哈

然后使用driver.get()方法,往内部传一个地址,我们就用淘宝网的地址。我们也就打开了下面的所示淘宝的网页界面。

driver = webdriver.Chrome()  # 创建谷歌浏览器        # TODO 执行浏览器操作    driver.get("https://www.taobao.com/")      driver.implicitly_wait(10)  # 智能化等待方法    driver.maximize_window()  # 最大化

4.3Xpath解析路径

我们要在淘宝网的搜索框中输入我们的商品,还要点搜索按钮,进而还需要登录(需要用户名、密码)。这都需要我们在网页上定位这些搜索框、搜索按钮、用户名框、密码框、登录按钮。所以打开淘宝网页的开发者模式,找到搜索框、搜索按钮、用户名框、密码框、登录按钮的xpath。

我们利用find_element_by_xpath()这个函数来解析对应的xpath

设置等待的时间,模拟人为操作

driver.find_element_by_xpath("//*[@id="q"]").send_keys(word)      time.sleep(random.randint(1, 3))     driver.find_element_by_xpath("//*[@id="J_TSearchForm"]/div[1]/button").click()    time.sleep(random.randint(1, 3))

开发者模式:

首先我们定位到搜索框,就在开发者模式的Elements下,copy  -->  copy xpath。复制到我们的find_element_by_xpath()函数中,其他的搜索按钮、用户名框、密码框、登录按钮也是这样找。

4.4 搜索商品关键字

在淘宝网上,根据我们所需要爬取的商品信息,在搜索框中搜索爬取的商品,比如说 帽子。

word = input("请输入要搜索的关键字:")    # TODO 创建浏览器    driver = webdriver.Chrome()         # TODO 执行浏览器操作    driver.get("https://www.taobao.com/")  # 传一个地址    driver.implicitly_wait(10)  # 智能化等待方法    driver.maximize_window()  # 最大化    driver.find_element_by_xpath("//*[@id="q"]").send_keys(word)  #     time.sleep(random.randint(1, 3))      driver.find_element_by_xpath("//*[@id="J_TSearchForm"]/div[1]/button").click()    time.sleep(random.randint(1, 3))

在搜索之后就出现一个登陆的界面,我们再根据4.3xpath解析路径的方法将我们的用户名,密码传进去,再进行登录。

代码如下:

"""用户账号及密码登录"""    driver.find_element_by_xpath("//*[@id="fm-login-id"]").send_keys("xxxxxxx")  # TODO 输入用户名    time.sleep(random.randint(1, 3))      driver.find_element_by_xpath("//*[@id="fm-login-password"]").send_keys("xxxxxxxx")  # TODO 输入密码    time.sleep(random.randint(1, 3))      driver.find_element_by_xpath("//*[@id="login-form"]/div[4]/button").click()    time.sleep(random.randint(1, 3))

不过此时会遇到一个问题:登陆的时候需要我们进行滑动验证

这是因为淘宝网检测出了selenium这个东西,尽管你人为地去滑动,但还是会登陆失败。

所以我们在创建出浏览器之后,随即改变浏览器内部的一些属性,可以网站避免检测出selenium的存在,就不需要我们进行滑动登录的验证了。

# 修改了浏览器的内部属性,跳过了登录的滑动验证    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",                           {"source": """Object.defineProperty(navigator, "webdriver", {get: () => undefined})"""})

4.5获取爬取商品具体信息

解析获取商品名称title、商品价格price、付款人数deal,店铺名称shop、店铺地址location、商品的详情页detail_url的数据

这时候我们需要借助一个插件:xpath helper  十分好用,可以写我们xpath的语法,来帮助我们定位商品的具体信息。

例:这一页的48个商品名称

下载地址:

链接:https://pan.baidu.com/s/1iCEbjnpa8dhTDScIhkvbZA  提取码:1uv9

找到第一个商品,找到商品列表,每个商品列表里面都有该商品的具体信息,比如商品名称、商品价格、付款人数,店铺名称、店铺地址、等等等的数据

我们要获取所有的div标签divs,然后再遍历divs去获取所需要的商品具体信息

具体代码:

def parse_data():    # 多个商品数据解析    divs = driver.find_elements_by_xpath("//div[@class="grid g-clearfix"]/div/div")  # 获取所有的div标签    for div in divs:          title = div.find_element_by_xpath(".//div[@class="row row-2 title"]/a").text  # 商品名字        price = div.find_element_by_xpath(".//strong").text + "元"  # 商品价格        deal = div.find_element_by_xpath(".//div[@class="deal-cnt"]").text  # 付款人数        shop = div.find_element_by_xpath(".//div[@class="shop"]/a/span[2]").text  # 店铺名称        location = div.find_element_by_xpath(".//div[@class="location"]").text  # 店铺地点        detail_url = div.find_element_by_xpath(".//div[@class="row row-2 title"]/a").get_attribute("href")  # 详情页地址        print(title, price, deal, shop, location, detail_url)

爬取第一页和第二页的商品信息,一页爬取完之后便点击下一页

for page in range(0, 2):        print(f"-----------------正在爬取第{page + 1}页-----------------")        # TODO 调用商品解析的函数        parse_data()        driver.find_element_by_xpath("//li[@class="item next"]/a[@class="J_Ajax num icon-tag"]").click()        time.sleep(random.randint(2, 3))

5、完整代码及结果

完整代码如下:

from selenium import webdriverimport timeimport randomdef parse_data():    divs = driver.find_elements_by_xpath("//div[@class="grid g-clearfix"]/div/div")  # 所有的div标签    for div in divs:         test = div.find_element_by_xpath(".//div[@class="row row-2 title"]/a").text  # 商品名字        price = div.find_element_by_xpath(".//strong").text + "元"  # 商品价格        deal = div.find_element_by_xpath(".//div[@class="deal-cnt"]").text  # 付款人数        name = div.find_element_by_xpath(".//div[@class="shop"]/a/span[2]").text  # 店铺名称        location = div.find_element_by_xpath(".//div[@class="location"]").text  # 店铺地点        detail_url = div.find_element_by_xpath(".//div[@class="row row-2 title"]/a").get_attribute("href")  # 详情页地址        print(test, price, deal, name, location, detail_url)if __name__ == "__main__":    word = input("请输入要搜索的关键字:")    # TODO 1、创建浏览器    driver = webdriver.Chrome()     # TODO 2、修改了浏览器的内部属性,跳过了登录的滑动验证    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",                           {"source": """Object.defineProperty(navigator, "webdriver", {get: () => undefined})"""})    # TODO 3、执行浏览器操作    driver.get("https://www.taobao.com/")      driver.implicitly_wait(10)  # 智能化等待方法    driver.maximize_window()  # 最大化    driver.find_element_by_xpath("//*[@id="q"]").send_keys(word)      time.sleep(random.randint(1, 3))      driver.find_element_by_xpath("//*[@id="J_TSearchForm"]/div[1]/button").click()    time.sleep(random.randint(1, 3))     """用户账号及密码登录"""    driver.find_element_by_xpath("//*[@id="fm-login-id"]").send_keys("xxxxxx")  # TODO 输入用户名    time.sleep(random.randint(1, 3))      driver.find_element_by_xpath("//*[@id="fm-login-password"]").send_keys("xxxxxxx")  # TODO 输入密码    time.sleep(random.randint(1, 3))      driver.find_element_by_xpath("//*[@id="login-form"]/div[4]/button").click()    time.sleep(random.randint(1, 3))     for page in range(0, 2):        print(f"-----------------正在爬取第{page + 1}页-----------------")        # TODO 调用商品解析的函数        parse_data()        driver.find_element_by_xpath("//li[@class="item next"]/a[@class="J_Ajax num icon-tag"]").click()        time.sleep(random.randint(2, 3))

爬取的结果如图:

二、存入数据库

from pymysql import *  # 连接MySQL数据库import pymysql

连接我们本机的数据库接着创建游标对象执行sql语句,将数据存入数据库表information中

(注意:在sql语句里,“不要用%或者+操作符来拼接SQL语句,应该使用占位符”,因为我使用了%拼接在运行的时候出错了,找了百度解决了这个问题)

mysql_obj = connect(host="127.0.0.1", user="root", password="xxxxxxxx", database="webcrawlers", port=3306,                        charset="utf8mb4")    # 创建游标    cur_obj = mysql_obj.cursor()    # TODO 就是不要用%或者+操作符来拼接SQL语句,应该使用占位符    cur_obj.execute(        "insert into Information(id, name_product, price_product, number_purchaser, name_store, address_store, detail_url) values(0, ("%s"), ("%s"), ("%s"), ("%s"), ("%s"), ("%s")) " , (            title, price, deal, shop, location, detail_url))    mysql_obj.commit()    cur_obj.close()    mysql_obj.close()

三、数据库数据导入csv文件并建模分析

import pandas as pdimport seaborn as snsimport matplotlib.pyplot as pltimport numpy as npimport pymysql

在将数据库导入csv文件,借助了这个博客python把mysql数据库中的数据表写入csv文件_程序员 小明的博客-CSDN博客

"""参考此博客https://blog.csdn.net/weixin_42304193/article/details/89607394将数据库数据导入csv文件"""class Test_myqsl(object):    # 运行数据库和建立游标对象    def __init__(self):        self.connect = pymysql.connect(host="127.0.0.1", port=3306, user="root", password="xxxxxxx", database="webcrawlers",                                  charset="utf8mb4")        # 返回一个cursor对象,也就是游标对象        self.cursor = self.connect.cursor(cursor=pymysql.cursors.DictCursor)    # 关闭数据库和游标对象    def __del__(self):        self.connect.close()        self.cursor.close()    def write(self):        # 将数据转化成DataFrame数据格式        data = pd.DataFrame(self.read())        # 把id设置成行索引        data_1 = data.set_index("id", drop=True)        # 写写入数据数据        pd.DataFrame.to_csv(data_1, "e:/python1/taobaodatatest.csv", encoding="gbk")        print("写入成功")    def read(self):        # 读取数据库的所有数据        data = self.cursor.execute("""select * from information""")        field_2 = self.cursor.fetchall()        # pprint(field_2)        return field_2# 封装def main():    write = Test_myqsl()    write.write()

此时,我们在e盘中的python1文件中,就有了taobaodatatest.csv这个文件。里面的数据是由webcrawlers数据库information这个表导入的。

在我们进行数据分析之前,我们要拿到商品的价格price_product、和购买人数number_purchase

这里面的数据包含了一些无用符号,比如说" "、万、+、人付款、元。我们需要它的数据进行分析。所以我们把这些符号处理一下,拿到我们所需要的数据。

# TODO 对csv文件进行符号、文字的替换    f = open("E:/python1/taobaodatatest.csv", encoding="gbk")    content_f = f.read()    with open("E:/python1/taobaodatatest.csv", "w", encoding="gbk") as f1:        t = content_f.replace(""", " ")        f1.write(t)    f.close()    f = open("E:/python1/taobaodatatest.csv", encoding="gbk")    content_f = f.read()    with open("E:/python1/taobaodatatest.csv", "w", encoding="gbk") as f2:        g = content_f.replace("万", "0000")        f2.write(g)    f.close()    f = open("E:/python1/taobaodatatest.csv", encoding="gbk")    content_f = f.read()    with open("E:/python1/taobaodatatest.csv", "w", encoding="gbk") as f3:        h = content_f.replace("+", "")        f3.write(h)    f.close()    f = open("E:/python1/taobaodatatest.csv", encoding="gbk")    content_f = f.read()    with open("E:/python1/taobaodatatest.csv", "w", encoding="gbk") as f4:        j = content_f.replace("人付款", "")        f4.write(j)    f.close()    f = open("E:/python1/taobaodatatest.csv", encoding="gbk")    content_f = f.read()    with open("E:/python1/taobaodatatest.csv", "w", encoding="gbk") as f5:        k = content_f.replace("元", "")        f5.write(k)    f.close()

将taobaodatatest.csv文件的特殊符号处理完之后,进行数据分析、建模

# TODO 1.分析商品价格对销量的影响    tbdata = pd.read_csv("e:/python1/taobaodatatest.csv", encoding="gbk")    sns.set(style="darkgrid")    sns.jointplot(x="price_product", y="number_purchaser", data=tbdata, kind="scatter", color="purple")    plt.rcParams["font.sans-serif"] = ["SimHei"]    plt.rcParams["axes.unicode_minus"] = False    plt.title("商品价格对销量的影响", loc="right")    plt.show()    # TODO 2.分析商品价格对销售总额的影响    plt.rcParams["font.sans-serif"] = ["SimHei"]    plt.rcParams["axes.unicode_minus"] = False    tbdata["GMV"] = (tbdata["price_product"]) * (tbdata["number_purchaser"])    sns.regplot(x="price_product", y="GMV", data=tbdata, color="purple")    plt.title("商品价格对销售总额的影响")    plt.show()    # TODO 3.分析不同省份的店铺数量分布    plt.rcParams["font.sans-serif"] = ["SimHei"]    plt.rcParams["axes.unicode_minus"] = False    plt.figure(figsize=(8, 4))    province = tbdata["address_store"]    province.value_counts().plot(kind="bar", color="purple")    plt.xticks(rotation=90)    plt.xlabel("省份")    plt.ylabel("店铺数量")    plt.title("不同省份的店铺数量分布")    plt.show()    # TODO 4.直观地表示价格、省份、销量三者之间的关系(这里采用三维绘图表示三者关系)    x, y = np.mgrid[-2:2:20j, -2:2:20j]    z = x * np.exp(-x ** 2 - y ** 2)    ax = plt.subplot(111, projection="3d")    ax.plot_surface(x, y, z, rstride=2, cstride=1, cmap=plt.cm.Blues_r)    ax.set_xlabel("price_product")    ax.set_ylabel("address_store")    ax.set_zlabel("number_purchaser")    plt.title("价格、省份、销量三者之间的关系")    plt.show()

在程序运行的时候,在最后的数据建模分析的时候出现了错误:

TypeError: cannot convert the series to这个错误。网上查了 - 极客分享">python报TypeError: cannot convert the series to- 极客分享

这篇中说:可能是出现了空值,这个空值也是很特殊,既不是null也不是none。然后我翻了我的数据库,发现爬取的数据,极个别商品没有商品价格、商品没有购买人数。这就导致我在计算总销售额的时候出现了这个错误

所以在对爬取数据存入数据库的时候,对xpath解析得到的:商品价格price、购买人数deal进行判定:当他们是  ""  的时候,我赋值一个0给它们。

if price == "":            price = 0        if deal == "":            deal = 0

此时爬取的数据进行分析结果如图:

标签: 商品价格

最新新闻:

新闻放送
Top