分享

[简单的python爬虫实战] 获取1688网页上的商品信息

 huowufenghuang 2019-05-16

语言:python 3.6 / 框架: Scrapy 1.5 /  数据库:Mysql 8.0 / IDE: pycharm

1. 生成项目

首先,安装好基本的软件。之后到项目文件夹处 按住 shift+右键,打开命令行模式。

执行 scrapy startproject [项目名] 生成项目文件。cd [项目名] 进入到项目文件夹中后执行 scrapy genspider <爬虫名> <domain/域名(起始页)> 生成爬虫文件。

2. 创建数据对象 items.py。在mysql中建立对应的数据表单。(注意表的字符编码,这里设置的数据编码是CHARACTER SET utf8 COLLATE utf8_general_ci)

class A1688Item_selloffer(scrapy.Item):
    title = scrapy.Field()     #标题
    company = scrapy.Field()   #公司
    price = scrapy.Field()     #售价
    sell = scrapy.Field()      #30天成交量
    method = scrapy.Field()    #销售模式
    rebuy = scrapy.Field()     #回头率
    address = scrapy.Field()   #地址
    subicon = scrapy.Field()   #服务保障

3.编写爬虫逻辑

import scrapy
from bs4 import BeautifulSoup
from A1688.items import A1688Item_selloffer #导入item类

KEYWORD="关键词"
PAGE='1'

class A1688SellofferSpider(scrapy.Spider):
    name = 'A1688-selloffer'
    # allowed_domains = ['www.1688.com']     #爬虫允许爬取的网址域名。
    # start_urls = ['https://www.1688.com/'] #需要爬取的链接的列表,response对象默认传递给 self.parse 函数处理。
    def start_requests(self):
        for page in range(1, int(PAGE)+1):
            url = 'https://s.1688.com/selloffer/offer_search.htm?keywords=%s&beginPage=%s' % (KEYWORD, page)
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        #实例化一个数据模型        
        item = A1688Item_selloffer()
        for tag in response.css('.sw-dpl-offer-item').extract():
            try:
                # 从response中利用css选择器提取出来的标签是文本形式,需要利用 BeautifulSoup 转换成BeautifulSoup.Tag 对象进行进一步提取。
                soup = BeautifulSoup(tag, 'lxml')

                item['title'] = soup.select(".sw-dpl-offer-photo img")[0].attrs['alt']
                item['company'] = soup.select(".sw-dpl-offer-companyName")[0].attrs['title']
                item['price'] = soup.select(".sw-dpl-offer-priceNum")[0].attrs['title']
                item['sell'] = soup.select(".sm-offer-tradeBt")[0].attrs['title']
                item['rebuy'] =soup.select(".sm-widget-offershopwindowshoprepurchaserate span")[2].string
                item['method']  = soup.select(".sm-widget-offershopwindowshoprepurchaserate i")[0].string
                #对于不一定能获取的数据,需要判断数据存在与否。
                if soup.select(".sm-offer-location")[0].attrs['title']:
                    address= soup.select(".sm-offer-location")[0].attrs['title']
                else:
                    address = " "
                item['address'] =address

                if soup.select(".sm-offer-subicon a"):
                    subicon = []
                    for i in soup.select(".sm-offer-subicon a"):
                        subicon.append(i.attrs['title'] + ',')
                    print(subicon)
                    item['subicon']=subicon
                else:
                    item['subicon'] = ' '
                #返回这个数据模型,交给 ITEM_PIPELINES 处理
                yield item
            except Exception as error:
                yield item
                print("出错了:", error)
                continue

4.建立数据管道

#连接数据库,获取cursor以便之后对数据就行增删查改
import pymysql
from A1688 import settings

# 创建DBPipeline类,在其中进行对数据库的操作。
class DBPipeline(object):
    def __init__(self):
        # 连接数据库。可以在settings中对数据库连接需要的参数进行设置
        self.connect = pymysql.connect(
            host=settings.MYSQL_HOST,
            port=settings.MYSQL_PORT,
            db=settings.MYSQL_DBNAME,
            user=settings.MYSQL_USER,
            passwd=settings.MYSQL_PASSWD,
            charset='utf8', #注意这里charset属性为 ‘utf8’,中间没有-,是因为数据库中的字符名称就是'utf8'
            use_unicode=True)

        # 创建数据库游标对象,通过cursor对象对数据库执行增删查改
        self.cursor = self.connect.cursor()
        print("数据库链接成功mysql connect succes")
        
    #重载方法process_item(self, item, spider):
    #返回一个具有数据的dict,或者item对象,或者抛出DropItem异常,被丢弃的item将不会被之后的pipeline组件所处理
    #利用这个方法,可以对item采集的数据进行增删查改,利用cursor执行sql语句,然后使用self.connect.commit()提交sql语句
    def process_item(self, item, spider):
        try:
            # 插入数据。利用execute()方法执行sql语句对数据库进行操作。这里执行的是写入语句 "insert into 表名(列名) value (数据)"
            # 需要注意的是。需要注意的是数据库的编码格式,以及sql语句的使用规范。(如varchar 类型的数据接收的是字符串,要带'')
            self.cursor.execute(
                "insert into a1688item_selloffer (title,company,price,sell,method,rebuy,address,subicon) value (%s,%s,%s,%s,%s,%s,%s,%s)"
                [item['title'],item['company'],item['price'],item['sell'],item['method'],item['rebuy'],item['address'],item['subicon']]
            )
            print("insert success")
            # 提交sql语句
            self.connect.commit()
        except Exception as error:
            # 出现错误时打印错误日志
            print('Insert error:', error)
        return item
5.修改settings
# 修改USER_AGENT,让服务器识别爬虫为浏览器
USER_AGENT =  "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"

#设置爬虫执行过程中使用的数据处理管道
ITEM_PIPELINES = {
    'A1688.pipelines.DBPipeline': 300, #这个数的范围是0-1000,这个数值确定了pipelines的运行顺序,数字越小越优先
}

# 设置与数据库连接相关的变量
MYSQL_HOST = 'localhost' # 主机域名,默认为本地链接
MYSQL_PORT = 3306        # 数据库端口,mysql一般默认用3306
MYSQL_DBNAME = 'a1688'   # 数据库名字
MYSQL_USER = 'root'      # 用户名
MYSQL_PASSWD = '******'  # 用户密码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多