前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Scrapy实战7: 分类爬取医疗信息网站图片

Scrapy实战7: 分类爬取医疗信息网站图片

作者头像
龙哥
发布2020-02-12 11:12:09
7750
发布2020-02-12 11:12:09
举报
文章被收录于专栏:Python绿色通道Python绿色通道

一、 前言

今天X先生带大家正真的实战:爬取医疗信息网站的图片及分类存储到本地和存储到MySql数据库。

读完本文,可能需要10到20分钟不等,你可以学到:Xpath语法再详解,实战,翻页、多页面爬取思想,数据存储三种方法:下载到本地、存储到Mysql数据库、存储到本地csv文件,开学前最后一批干货,满满的。

评论区置顶第一期赠书获奖名单(昨天已经在极简交流群里公布过啦!)

二、基本知识回顾

1.Xpath基本使用
1)安装方法

直接推荐方法:豆瓣源安装(其他安装方法自己可百度)

代码语言:javascript
复制
pip install -i https://pypi.douban.com/simple/ lxml
2)基础语法及使用学习:

【Python | 边学边敲边记】第五次:Xpath实战训练 该文章详细介绍了Xpath的基本使用方法,包括常用语法介绍。

2.数据库操作之Pymysql
1)安装方法

直接推荐方法:豆瓣源安装(其他安装方法自己可百度)

代码语言:javascript
复制
pip install -i https://pypi.douban.com/simple/ pymysql
2)基本使用介绍
代码语言:javascript
复制
import pymysql

# 数据库连接
conn = pymysql.connect(host = "localhost",port = ,user = "你的数据库登录名",
password = "你的数据库登录名",charset="utf8",database = "你的数据库名称")

# 使用cursor()方法获取操作游标
cur = conn.cursor()
# 执行sql语句(可以是增删查改任意操作)
cur.execute(sql)
# 提交会话
conn.commit()
# 关闭数据库连接

三、看代码,边学边敲边记Xpath系统实战训练

1.图解我们要爬取的网站

网站结构图解

我们爬取的主页面是http://www.med361.com,它的下面有很多医疗商品类别(图中我们用1:n的形式给出),而每一个category(类别)下又有多个product(商品)(图中我们用1:n的形式给出),当然进入详细商品主页面后,还会有很多url,后面爬取时细说。

2.访问主页面,利用Xpath来获取所有商品类别url
(1)基础代码
代码语言:javascript
复制
'''
author : 极简XksA
data : 2018.8.31
goal : 爬取医疗网站图片
'''

import requests
from lxml import etree

def get_respones_data(branch_url):
    # requests 发送请求
    get_response = requests.get(branch_url)
    # 将返回的响应码转换成文本(整个网页)
    get_data = get_response.text
    # 解析页面
    a = etree.HTML(get_data)
    return a
# 主页面
mian_url = "http://www.med361.com"
# 发送请求,获取Xpath格式页面
response_01 = get_respones_data(mian_url)

# 不同医疗商品类别url
# 上一页
branch_url_1 = response_01.xpath("/html/body/div[2]/div/div/div/div[1]/ul/li/a/@href")
# 下一页
branch_url_2 = response_01.xpath("/html/body/div[2]/div/div/div/div[2]/ul/li/a/@href")
print(branch_url_1)
print(branch_url_2)
(2)Xpath路径选择分析

1)图片分析:

商品类别url分析01

商品类别url分析022)文字解说:

代码语言:javascript
复制
# 上一页
"/html/body/div[2]/div/div/div/div[1]/ul/li[1]/a"
"/html/body/div[2]/div/div/div/div[1]/ul/li[4]/a"
"/html/body/div[2]/div/div/div/div[1]/ul/li[10]/a"
# 下一页
"/html/body/div[2]/div/div/div/div[2]/ul/li[1]/a"

上面是我选取的几个不同类别的医疗商品的Xpath路径,可以发现规律,在改变的只有最后一个li标签,而我们要获取的是a标签href属性(页面url在里面),而且上一页与下一页的区别为最后一个div序号不同,所以Xpath路径为:

代码语言:javascript
复制
"/html/body/div[2]/div/div/div/div[1]/ul/li/a/@href"
and
"/html/body/div[2]/div/div/div/div[2]/ul/li/a/@href"
(3)运行结果为

商品类别url获取结果

(4)修正数据

通过结果我们易看出,我们所获取到的url和我们想象中还是有差别的,比如没有www或者http,嘿嘿,不过通过页面跳转分析我们知道我们现在获取到的是商品分类url的后面部分,而前面部分则为:http://www.med361.com,处理一下:

代码语言:javascript
复制
# 合并所有类别
branch_url = branch_url_1 + branch_url_2
# 将url处理成我们能直接访问的类型
for i in range(len(branch_url)):
    branch_url[i] = mian_url + branch_url[i].replace('/..','')
print(branch_url)

运行结果:

商品类别url到目前为止,这一部分我们就完成了。

3.访问分页面,利用Xpath来获取所有商品详情url
(1)基础代码
代码语言:javascript
复制
# 某个医疗商品类别url
branch_url_01 = "http://www.med361.com/category/c-456-b0.html"
# 发送请求
response_02 = get_respones_data(branch_url_01)
# Xpath 获取所有单个商品url
url_list = response_02.xpath('//*[@id="ddbd"]/form/dl/dd[2]/a/@href')
# 将url处理成我们能直接访问的类型
for i in range(len(url_list)):
    url_list[i] = mian_url + url_list[i]
print(url_list)
(2)Xpath路径选择分析

图片分析:

单个商品url Xpath路径分

文字解说:

代码语言:javascript
复制
"//*[@id="ddbd"]/form/dl[1]/dd[2]/a"
"//*[@id="ddbd"]/form/dl[3]/dd[2]/a"
"//*[@id="ddbd"]/form/dl[9]/dd[2]/a"

上面是我选取的几个不同的医疗商品的Xpath路径,可以发现规律,在改变的只有最后一个dl标签,而我们要获取的是a标签href属性(页面详情url在里面),所以Xpath路径为:

代码语言:javascript
复制
"//*[@id="ddbd"]/form/dl[9]/dd[2]/a/@href"
(3)运行结果为

单个商品详情url

(4)补充:翻页

1)图片介绍

翻页介绍

2)代码实现

代码语言:javascript
复制
# 某个医疗商品类别url
branch_url_01 = "http://www.med361.com/category/c-456-b0.html"
# 发送请求
response_02 = get_respones_data(branch_url_01)
# Xpath 获取所有单个商品url
url_list = response_02.xpath('//*[@id="ddbd"]/form/dl/dd[2]/a/@href')
# Xpath 获取所有翻页url
url_paging = response_02.xpath('//*[@id="pager"]/a/@href')
# 将翻页url处理成我们能直接访问的类型
for i in range(len(url_paging)):
    url_paging[i] = mian_url + url_paging[i].replace('/..','')
# 将商品url处理成我们能直接访问的类型
for i in range(len(url_list)):
    url_list[i] = mian_url + url_list[i]
print(url_list)
for i in range(len(url_paging)):
    time.sleep()
    # 发送请求
    response_03 = get_respones_data(branch_url_01)
    # Xpath 获取所有单个商品url
    url_list = response_03.xpath('//*[@id="ddbd"]/form/dl/dd[2]/a/@href')
    # 将商品url处理成我们能直接访问的类型
    for i in range(len(url_list)):
        url_list[i] = mian_url + url_list[i]
    print(url_list)

到目前为止,这一部分我们也完成了。

4.访问单个商品页面,利用Xpath来获取商品名称和介绍图片url
(1)基础代码
代码语言:javascript
复制
url_one = "http://www.med361.com/product/p-4357.html"
response_04 = get_respones_data(url_one)


# 1.医疗器材名称(Medical equipment name)
m_e_name = response_04.xpath('//*[@id="product-intro"]/ul/li[1]/h1/text()')[].strip()
print("医疗器材名称:" + m_e_name)
# 2.图片介绍(Picture introduction)
picture_i = response_04.xpath('//*[@id="content"]/div/div[3]/div[2]/div/div/div[1]/div[2]/div/img/@src')
# 解决获取图片链接不完全问题
for i in range(len(picture_i)):
    if mian_url not in picture_i[i]:
        picture_i[i] = mian_url + picture_i[i]
print(picture_i)
(2)Xpath路径选择分析

1)图片分析:

单个商品图片介绍Xpath

2)文字解说:

代码语言:javascript
复制
'//*[@id="content"]/div/div[3]/div[2]/div/div/div[1]/div[2]/div[4]/img'
'//*[@id="content"]/div/div[3]/div[2]/div/div/div[1]/div[2]/div[5]/img'
'//*[@id="content"]/div/div[3]/div[2]/div/div/div[1]/div[2]/div[6]/img'

上面是我选取的几个不同的医疗商品的图片的Xpath路径,可以发现规律,在改变的只有最后一个div标签,而我们要获取的是img标签src属性(页面详情url在里面),所以Xpath路径为:

代码语言:javascript
复制
"//*[@id="content"]/div/div[3]/div[2]/div/div/div[1]/div[2]/div/img/@src"
(3)运行结果为

单个商品详细信息

到目前为止,这一部分我们也完成了。

5.整合上面的2、3、4,系统爬取所有类别所有商品的所有名称和图片信息
(1)基础代码
代码语言:javascript
复制
import requests
from lxml import etree
import time,random

# 获取事先爬好、检测了的代理ip
with open("new_http.txt",encoding="utf-8") as file :
    t0 = file.read()
    s0 = t0.split(",")

def get_respones_data(branch_url):
    # 获取代理ip
    i = random.randint(,len(s0)-2)
    proxies = {
            "http": s0[i]
    }
    # requests 发送请求
    get_response = requests.get(branch_url,proxies = proxies)
    # 将返回的响应码转换成文本(整个网页)
    get_data = get_response.text
    # 解析页面
    a = etree.HTML(get_data)
    return a

# 主页面
mian_url = "http://www.med361.com"
# 发送请求
response_01 = get_respones_data(mian_url)

# 不同医疗商品类别url
branch_url_1 = response_01.xpath("/html/body/div[2]/div/div/div/div[1]/ul/li/a/@href")
branch_url_2 = response_01.xpath("/html/body/div[2]/div/div/div/div[2]/ul/li/a/@href")
# 合并所有类别
branch_url = branch_url_1 + branch_url_2
# 将url处理成我们能直接访问的类型
for i in range(len(branch_url)):
    branch_url[i] = mian_url + branch_url[i].replace('/..','')
print(branch_url)   # 所有类别

# 商品名称集
commodity_name = []
# 商品介绍图片集
commodity_intr = []

for i in range(len(branch_url)):      # 不同类别
    time.sleep(random.randint(,))
    response_02 = get_respones_data(branch_url[i])
    url_list_all = []
    # Xpath 获取所有单个商品url
    url_list = response_02.xpath('//*[@id="ddbd"]/form/dl/dd[2]/a/@href')
    # Xpath 获取所有翻页url
    url_paging = response_02.xpath('//*[@id="pager"]/a/@href')
    # 将翻页url处理成我们能直接访问的类型
    for j in range(len(url_paging)):
        url_paging[j] = mian_url + url_paging[j].replace('/..', '')
    # 将商品url处理成我们能直接访问的类型
    for j in range(len(url_list)):
        url_list[j] = mian_url + url_list[j]
    url_list_all = url_list
    # 单个类别翻页
    for n in range(len(url_paging)):
        time.sleep()
        # 发送请求
        response_03 = get_respones_data(url_paging[n])
        # Xpath 获取所有单个商品url
        url_list = response_03.xpath('//*[@id="ddbd"]/form/dl/dd[2]/a/@href')
        # 将商品url处理成我们能直接访问的类型
        for j in range(len(url_list)):
            url_list[j] = mian_url + url_list[j]
        url_list_all = url_list_all + url_list      # 获取了单个类别所有商品url

    for m in range(len(url_list_all)):
        time.sleep()
        response_03 = get_respones_data(url_list_all[m])
        # 1.医疗器材名称(Medical equipment name)
        m_e_name = response_03.xpath('//*[@id="product-intro"]/ul/li[1]/h1/text()')[].strip()
        commodity_name.append(m_e_name)      # 获得商品名称
        # print("医疗器材名称:" + m_e_name)
        # 2.图片介绍(Picture introduction)
        picture_i = response_03.xpath('//*[@id="content"]/div/div[3]/div[2]/div/div/div[1]/div[2]/div/img/@src')
        # 解决获取图片链接不完全问题
        for i in range(len(picture_i)):
            if mian_url not in picture_i[i]:
                picture_i[i] = mian_url + picture_i[i]
        commodity_intr.append(picture_i)
        # print(picture_i)         # 获得介绍图片
(2)文件下载存储到本地
代码语言:javascript
复制
# 下载图片函数
'''
folder_name : 文件夹名称,按图片简介
picture_address : 一组图片的链接
'''
def download_pictures(folder_name, picture_address):
    # 在G盘必须有 Medical这个文件夹
    file_path = r'G:\Medical\{0}'.format(folder_name)
    if not os.path.exists(file_path):
        # 新建一个文件夹
        os.mkdir(os.path.join(r'G:\Medical', folder_name))
    # 下载图片保存到新建文件夹
    for i in range(len(picture_address)):
        # 下载文件(wb,以二进制格式写入)
        with open(r'G:\Medical\{0}\0{1}.jpg'.format(folder_name,i+), 'wb') as f:
            time.sleep()
            # 根据下载链接,发送请求,下载图片
            response = requests.get(picture_address[i])
            f.write(response.content)

把代码加到正确位置,并调用该函数。

(3)存储到MySql数据库
  • Mysql里的medical数据库中新建一个表:
代码语言:javascript
复制
CREATE TABLE `medical`.`data_med` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `med_name` VARCHAR() NULL,
  `url_01` VARCHAR() NULL,
  `url_02` VARCHAR() NULL,
  `url_03` VARCHAR() NULL,
  `url_04` VARCHAR() NULL,
  `url_05` VARCHAR() NULL,
  `url_06` VARCHAR() NULL,
  `url_07` VARCHAR() NULL,
  `url_08` VARCHAR() NULL,
  `url_09` VARCHAR() NULL,
  `url_10` VARCHAR() NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
  • 数据保存到数据库:
代码语言:javascript
复制
# 数据库连接
conn = pymysql.connect(host = "localhost",port = ,user = "你的数据库登录名",
password = "你的数据库登录名",charset="utf8",database = "你的数据库名称")

def sql_insert(sql):
    cur = conn.cursor()
    cur.execute(sql)
    conn.commit()

把代码加到正确位置,并调用该函数。

(3)字段内容存储到`csv`文件
代码语言:javascript
复制
# 存储进CSV文件
'''
list_info : 存储内容列表
'''
def file_do(list_info):
    # 获取文件大小(先新建一个csv文件)
    file_size = os.path.getsize(r'G:\medical.csv')
    if file_size == :     # 只打印一次表头
        # 表头
        name = ['名称简介','url_01','url_02','url_03','url_04','url_05','url_06','url_07','url_08','url_09','url_10']
        # 建立DataFrame对象
        file_test = pd.DataFrame(columns=name, data=list_info)
        # 数据写入
        file_test.to_csv(r'G:\medical.csv', encoding='utf-8',index=False)
    else:
        with open(r'G:\medical.csv','a+',newline='') as file_test :
            # 追加到文件后面
            writer = csv.writer(file_test)
            # 写入文件
            writer.writerows(list_info)

把代码加到正确位置,并调用该函数。

(4)运行效果简单展示

运行效果01

运行效果02

【完】

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python绿色通道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、 前言
  • 二、基本知识回顾
    • 1.Xpath基本使用
      • 2)基础语法及使用学习:
        • 2.数据库操作之Pymysql
        • 三、看代码,边学边敲边记Xpath系统实战训练
          • 1.图解我们要爬取的网站
            • 2.访问主页面,利用Xpath来获取所有商品类别url
              • 3.访问分页面,利用Xpath来获取所有商品详情url
                • 4.访问单个商品页面,利用Xpath来获取商品名称和介绍图片url
                  • 5.整合上面的2、3、4,系统爬取所有类别所有商品的所有名称和图片信息
                  相关产品与服务
                  数据库
                  云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档