Python爬取淘宝商品信息并生成Excel

小知识,大挑战!本文正在参与“   程序员必备小知识   ”创作活动

作者的其他平台:

| CSDN:blog.csdn.net/qq_4115394…

| 掘金:juejin.cn/user/651387…

| 知乎:www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

| 公众号:1024笔记

本文大概9989字,建议阅读25分钟

1 前言

后台有很多小伙伴私信问我关于python爬虫的知识和学习资源,今天这篇文章就简单介绍下python爬虫的知识点,并以爬取淘宝网的商品信息存到excel表格中进行演示,同样的本文的源码会同步至github,欢迎下载使用。

2 爬虫相关知识

在进行爬虫之前,需要先了解一些关于爬虫的基本知识。

首先我们需要先了解下爬虫的基本原理:

基本的网页请求的过程都可以分为以下两个步骤:

1、Request (请求):每一个展示在用户面前的网页都必须经过这一步,也就是向服务器发送访问请求。

2、Response(响应):服务器在接收到用户的请求后,会验证请求的有效性,然后向用户(客户端)发送响应的内容,客户端接收服务器响应的内容,将内容展示出来(即网页),如下图所示。

图片

网页请求的方式也分为两种:

1、GET:最常见的方式,一般用于获取或者查询资源信息,也是大多数网站使用的方式,响应速度快。

2、POST:相比 GET 方式,多了以表单形式上传参数的功能,因此除查询信息外,还可以修改信息。

所以,在写爬虫前我们要先确定向谁发送请求,并且用什么方式发送。

向谁发送请求,那我们就需要了解请求的url地址,以淘宝网的眼镜的url为例:

https://s.taobao.com/search?q=%E7%9C%BC%E9%95%9C&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306
复制代码

这里眼镜中文被转义了:

图片

这里我们只需要知道q后面的值就是我们搜索的商品的名字就可以了,后面其他的参数这里暂时对我们没用。

因为爬虫并不只爬取一页的信息,我们跳转到下一页:

图片

图片

可以发现s的值=44*(页码-1)。

接着ctrl+U组合键打开源码,可以发现有一个g_page_config 的json串,里面的data值如下:

,"data":{"postFeeText":"运费","trace":"msrp_auction","auctions":[{"p4p":1,"p4pSameHeight":true,"nid":"536766094512","category":"","pid":"","title":"近视\u003cspan class\u003dH\u003e眼镜\u003c/span\u003e男有度数超轻全框\u003cspan class\u003dH\u003e眼镜\u003c/span\u003e框半框舒适可配\u003cspan class\u003dH\u003e眼镜\u003c/span\u003e防雾眼睛近视镜","raw_title":"丹阳眼镜眼镜框眼镜架眼睛框防辐射光学镜","pic_url":"//g-search1.alicdn.com/img/bao/uploaded/i4/imgextra/i2/104870285060645671/TB2ulgla4vzQeBjSZPfXXbWGFXa_!!0-saturn_solar.jpg"
复制代码

这里postFeeText即为运费,raw_title为标题,pic_url即为展示图片的地址,

图片

view_price:运费;

nick:商铺的名称;

item_loc:地址;

view_sales:销售量。

以上的数据即对应下面的这些信息:

图片

请求方式可以F12,然后再network--->headers--->request Method找到:

图片

在了解上面的基本内容之后我们就可以写一个小型的爬虫了,比如下面的代码:

 #导入requests包
import requests       
url = 'https://s.taobao.com/search?q=%E7%9C%BC%E9%95%9C&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306&bcoffset=3&ntoffset=3&p4ppushleft=1%2C48&s=44'
#Get方式获取网页数据
strhtml = requests.get(url)
print(strhtml.text)
复制代码

图片

这样就将页面的内容获取并以html的格式展示出来了。

使用 requests 库请求网站加载库使用的语句是 import+库的名字。在上述过程中,加载 requests 库的语句是:import requests

用 GET 方式获取数据需要调用 requests 库中的 get 方法,使用方法是在 requests 后输入英文点号,如下所示:

requests.get
复制代码

将获取到的数据存到 strhtml 变量中,代码如下:

strhtml = request.get(url)
复制代码

这个时候 strhtml 是一个 URL 对象,它代表整个网页,但此时只需要网页中的源码,下面的语句表示网页源码:

strhtml.text
复制代码

3 实战

接下来我们完整的爬取淘宝的信息,主要爬取的信息是:商品名称、店铺名称、价格、地区、付款人数。

首先我们定义一个函数获取请求的url:

# 前面介绍q即为查询的商品的名称,所以这里定义为变量,方便后面重复使用
def Geturls(q, x):
    url = "https://s.taobao.com/search?q=" + q + "&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm" \
                                                 "=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306 "
    urls = []
    urls.append(url)
    if x == 1:
        return urls
    for i in range(1, x ):
        url = "https://s.taobao.com/search?q="+ q + "&commend=all&ssid=s5-e&search_type=item" \
              "&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306" \
              "&bcoffset=3&ntoffset=3&p4ppushleft=1%2C48&s=" + str(
            i * 44)
        urls.append(url)
    return urls
复制代码

然后定义一个函数来获取html的页面:

def GetHtml(url):
    #这里的请求get请求
    r = requests.get(url,headers =headers)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    return r
复制代码

然后定义一个函数获取商品的信息并插入excel:

首先介绍一个re库:

re库是python的标准库

re库采用raw string类型表示正则表达式,表示为:r'test'

原生字符串(raw string)是不包含转义符的字符串。

Re库主要功能函数如下:

图片

这里我们使用findall()函数提取信息,比如:

   a = re.findall(r'"raw_title":"(.*?)"', html)
复制代码
def GetandintoExcel(html):
    global count
    # 商品名称
    a = re.findall(r'"raw_title":"(.*?)"', html)
    # 店铺名称
    b = re.findall(r'"nick":"(.*?)"', html)
    # 商品价格
    c = re.findall(r'"view_price":"(.*?)"', html)
    # 地区
    d = re.findall(r'"item_loc":"(.*?)"', html)
    # 销售量
    e = re.findall(r'"view_sales":"(.*?)"', html)
    x = []
    for i in range(len(a)):
        try:
            x.append((a[i],b[i],c[i],d[i],e[i]))
        except IndexError:
            break
    i = 0
    for i in range(len(x)):
       worksheet.write(count + i + 1, 0, x[i][0])
       worksheet.write(count + i + 1, 1, x[i][1])
       worksheet.write(count + i + 1, 2, x[i][2])
       worksheet.write(count + i + 1, 3, x[i][3])
       worksheet.write(count + i + 1, 4, x[i][4])
    count = count +len(x)
    return print("数据爬取完成")
复制代码

主函数如下:

if __name__ == "__main__":
    count = 0
    # 下面的cookie要改成自己的
    headers = {
        "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
        ,"cookie":"t=dc3b73639f4d5652aee8e9f52d7d0c41; sgcookie=E100VfIm5WNNIHQbxK40GoWlA%2BiEh8%2BL3IfWZ8gaPQLmeINstkbFpvtbviklWcVtFdWGQqp2UpMRm4mVXJeOwD1RzA%3D%3D; tracknick=%5Cu5C0F%5Cu5C0F%5Cu5C0F%5Cu5C0F%5Cu54466; _cc_=UtASsssmfA%3D%3D; thw=cn; enc=l%2Fjb6N5FBl9K0ekOiije0dOrXynlA1PT6kAWiXlE8MP7XwVwWABeB1r%2F4%2FN%2FROmEcqBpM4Uk%2FlCcbvHxEX4HhA%3D%3D; cna=E7gdGOrz1lwCAXOs+dCyLVoL; _m_h5_tk=b3004b87cb6eecc0cc7c7154acf7a244_1606566002810; _m_h5_tk_enc=082f300176ed45b823551f15ca981ee0; cookie2=2c290690f10861f7bdd981cba5ac078f; v=0; _tb_token_=0a7840e5536b; JSESSIONID=CE9BABF53453F46B8B6A2FAA274428C1; alitrackid=www.taobao.com; lastalitrackid=www.taobao.com; hng=CN%7Czh-CN%7CCNY%7C156; xlly_s=1; _samesite_flag_=true; tfstk=cVuOB9wPApvG8ZVKacKhcclUWCOhZtfTn1wAkQuqyoMJW-7AiGgoy0ZkfSPvIBC..; l=eBjdYUdPOiL-FAJDBOfwourza77OSIRAguPzaNbMiOCPOZCp53UFWZR2YsT9C3GVh6RXR3rEk3ObBeYBqIv4n5U62j-la_kmn; isg=BE5OFMfVnXt4DynJaP_rUvlZnyQQzxLJN80UA3iXutEM2-414F9i2fSZEwe3Qwrh"
                }
    q = input("你想爬取的商品是:")
    x = int(input("你想爬取几页数据:"))
    urls = Geturls(q,x)
    workbook = xlsxwriter.Workbook(q+".xlsx")
    worksheet = workbook.add_worksheet()
    worksheet.set_column('A:A', 70)
    worksheet.set_column('B:B', 40)
    worksheet.set_column('C:C', 20)
    worksheet.set_column('D:D', 20)
    worksheet.set_column('E:E', 20)
    worksheet.write('A1', '商品名称')
    worksheet.write('B1', '店铺名称')
    worksheet.write('C1', '价格')
    worksheet.write('D1', '地区')
    worksheet.write('E1', '付款人数')
    xx = []
    for url in urls:
        html = GetHtml(url)
        s = GetandintoExcel(html.text)
        time.sleep(5)
    workbook.close()
复制代码

最后运行程序:

图片

图片

以上就是如何使用python爬取淘宝信息的内容,全部代码如下:

import re
import  requests
import xlsxwriter
import  time
import math

def Geturls(q, x):
    url = "https://s.taobao.com/search?q=" + q + "&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm" \
                                                 "=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306 "
    urls = []
    urls.append(url)
    if x == 1:
        return urls
    for i in range(1, x ):
        url = "https://s.taobao.com/search?q="+ q + "&commend=all&ssid=s5-e&search_type=item" \
              "&sourceId=tb.index&spm=a21bo.2017.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170306" \
              "&bcoffset=3&ntoffset=3&p4ppushleft=1%2C48&s=" + str(
            i * 44)
        urls.append(url)
    return urls

def GetHtml(url):
    r = requests.get(url,headers =headers)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    return r
    
def GetandintoExcel(html):
    global count
    a = re.findall(r'"raw_title":"(.*?)"', html)
    b = re.findall(r'"nick":"(.*?)"', html)
    c = re.findall(r'"view_price":"(.*?)"', html)
    d = re.findall(r'"item_loc":"(.*?)"', html)
    e = re.findall(r'"view_sales":"(.*?)"', html)
    x = []
    for i in range(len(a)):
        try:
            x.append((a[i],b[i],c[i],d[i],e[i]))
        except IndexError:
            break
    i = 0
    for i in range(len(x)):
       worksheet.write(count + i + 1, 0, x[i][0])
       worksheet.write(count + i + 1, 1, x[i][1])
       worksheet.write(count + i + 1, 2, x[i][2])
       worksheet.write(count + i + 1, 3, x[i][3])
       worksheet.write(count + i + 1, 4, x[i][4])
    count = count +len(x)
    return print("数据爬取完成")
    
if __name__ == "__main__":
    count = 0
    headers = {
        "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
        ,"cookie":"t=dc3b73639f4d5652aee8e9f52d7d0c41; sgcookie=E100VfIm5WNNIHQbxK40GoWlA%2BiEh8%2BL3IfWZ8gaPQLmeINstkbFpvtbviklWcVtFdWGQqp2UpMRm4mVXJeOwD1RzA%3D%3D; tracknick=%5Cu5C0F%5Cu5C0F%5Cu5C0F%5Cu5C0F%5Cu54466; _cc_=UtASsssmfA%3D%3D; thw=cn; enc=l%2Fjb6N5FBl9K0ekOiije0dOrXynlA1PT6kAWiXlE8MP7XwVwWABeB1r%2F4%2FN%2FROmEcqBpM4Uk%2FlCcbvHxEX4HhA%3D%3D; cna=E7gdGOrz1lwCAXOs+dCyLVoL; _m_h5_tk=b3004b87cb6eecc0cc7c7154acf7a244_1606566002810; _m_h5_tk_enc=082f300176ed45b823551f15ca981ee0; cookie2=2c290690f10861f7bdd981cba5ac078f; v=0; _tb_token_=0a7840e5536b; JSESSIONID=CE9BABF53453F46B8B6A2FAA274428C1; alitrackid=www.taobao.com; lastalitrackid=www.taobao.com; hng=CN%7Czh-CN%7CCNY%7C156; xlly_s=1; _samesite_flag_=true; tfstk=cVuOB9wPApvG8ZVKacKhcclUWCOhZtfTn1wAkQuqyoMJW-7AiGgoy0ZkfSPvIBC..; l=eBjdYUdPOiL-FAJDBOfwourza77OSIRAguPzaNbMiOCPOZCp53UFWZR2YsT9C3GVh6RXR3rEk3ObBeYBqIv4n5U62j-la_kmn; isg=BE5OFMfVnXt4DynJaP_rUvlZnyQQzxLJN80UA3iXutEM2-414F9i2fSZEwe3Qwrh"
                }
    q = input("你想爬取的商品是:")
    x = int(input("你想爬取几页数据:"))
    urls = Geturls(q,x)
    workbook = xlsxwriter.Workbook(q+".xlsx")
    worksheet = workbook.add_worksheet()
    worksheet.set_column('A:A', 70)
    worksheet.set_column('B:B', 40)
    worksheet.set_column('C:C', 20)
    worksheet.set_column('D:D', 20)
    worksheet.set_column('E:E', 20)
    worksheet.write('A1', '商品名称')
    worksheet.write('B1', '店铺名称')
    worksheet.write('C1', '价格')
    worksheet.write('D1', '地区')
    worksheet.write('E1', '付款人数')
    xx = []
    for url in urls:
        html = GetHtml(url)
        s = GetandintoExcel(html.text)
        time.sleep(5)
    workbook.close()
复制代码

4 再说一句:反爬虫

最后说一下爬虫的合法性。几乎每一个网站都有一个名为 robots.txt 的文档,当然也有部分网站没有设定 robots.txt。对于没有设定 robots.txt 的网站可以通过网络爬虫获取没有口令加密的数据,也就是该网站所有页面数据都可以爬取。如果网站有 robots.txt 文档,就要判断是否有禁止访客获取的数据。
以百度为例,在浏览器中访问 www.baidu.com/robots.txt。

图片

可以看到百度可以允许部分爬虫访问它的部分路径,而对于没有得到允许的用户,则全部禁止爬取的,代码如下:

User-Agent:\*  
Disallow:/
复制代码

这一句代码的意思是除前面指定的爬虫外,不允许其他爬虫爬取任何数据。

所以我们爬虫最好要遵从网站的规定和合法性。

然后很多的网站其实都是有反爬虫机制的。说到底爬虫其实就是通过代码来模拟人的浏览访问行为,进行数据的批量抓取。所以当抓取的数据量逐渐增大时,就会给被访问的服务器造成很大的压力,甚至有可能崩溃,所以很多的网站都会采取一些反爬策略。

服务器如何识别是否是爬虫行为?第一种比较初级的反爬机制就是通过检查连接的 useragent 来识别到底是浏览器访问,还是代码访问的。如果是代码访问的话,访问量增大时,服务器会直接封掉来访 IP。

前面说到了我们可以找到 URL、Form Data、Request headers等信息,而服务器识别浏览器访问的方法就是判断 keyword 是否为 Request headers 下的 User-Agent,这时候我们可以再请求头中来封装自己构造浏览器的请求头。

图片

因此,我们只需要构造这个请求头的参数。创建请求头部信息即可,代码如下:

headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'}  
response = request.get(url,headers=headers)
复制代码

我们要知道爬虫的话访问频率是很快的,我们人为一秒钟可能会看一个图,而代码的话一秒钟可以爬取上百、上千张图,这样同样会造成服务器的压力,还是会被反爬,所以第二种反爬机制就是我们常见的验证码。就是统计每个IP的访问频率,并且如果该频率超过设定的阈值,就会返回一个验证码,如果真的是用户访问的话,用户就会填写,然后继续访问,如果是代码访问的话,就会被封 IP。

这时候我们有两种解决方式:第一种方式就是常用的增设延时,比如每 5秒钟抓取一次,代码如下:

import time  
time.sleep(5)
复制代码

但是这种方式就会导致爬虫效率的降低。那么第二种解决方式就是设置代理ip。而且requests 也有相应的 proxies 属性。

首先,构建自己的代理 IP 池,将其以字典的形式赋值给 proxies,然后传输给 requests,代码如下:

proxies={
"http":"http://xx.xx.x.xx.xxx",
"https":"http://xx.xx.x.xx.xxx",
}
response = requests.get(url, proxies=proxies)
复制代码

5 总结

最后的最后,爬虫可以作为一项技能和兴趣来学习,不要违法网站的规定利用爬虫做一些违法的行为。

另外所有实战文章的源码都会同步至github,有需要的欢迎下载使用。

本文源码地址:github.com/JiangXia-10…

最后如果觉得本文写得不错,就点下赞和再看推荐给更多的人呗。

欢迎关注微信公众号:1024笔记获取更多文章!

今日推荐

如何用Python将PDF转换成Word

Python入门(六):调用自定义函数

Python入门(五):字典(Dict)的使用

Python入门(四):集合(set)的使用

猜你喜欢

转载自juejin.im/post/7016673505928282125