29.selenium多页抓取,并保存到三大主流数据库

在上一篇中使用scrapy-splash抓取了单页js加载的信息,只抓取一页对爬虫来说简直是高射炮打蚊子。本篇将抛却fiddler奇淫巧技,通过最基础的方式研究如何抓取多页信息。



这样一个网页,看着很简单,但它下面的网页跳转与网址无任何关系,点击网页跳转,网址岿然不动。如果不加载js,连下面的网页跳转都没有。哭戚戚。



先在pycharm中新建个文件作为练习。
爬取一页的代码如下:
# coding:utf-8
from selenium import webdriver
from scrapy.selector import Selector

url = "http://www.zjzfcg.gov.cn/purchaseNotice/index.html?categoryId=3001"
driver = webdriver.Chrome()
driver.get(url)
data = driver.page_source
response = Selector(text=data)  # 这里如果不使用"text=data",直接写data将会报错 'str' object has no attribute 'text'
infodata = response.css(".items p")
for infoline in infodata:
    city = infoline.css(".warning::text").extract()[0].replace("[", "").replace("·", "").strip()
    issuescate = infoline.css(".warning .limit::text").extract()[0]
    title = infoline.css("a .underline::text").extract()[0].replace("]", "")
    publish_date = infoline.css(".time::text").extract()[0].replace("[", "").replace("]", "")
    print(city+"--"+title+"--"+issuescate+"--"+publish_date)
driver.close()

抓到的信息如下:



那现在可以考虑翻页的事情了。
可以使用webdriver的find_element_by_css_selector定位到元素,然后使用click方法实现点击,OK,做个小测试:

# -*- coding: utf-8 -*-
# @AuThor  : frank_lee

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import time


class ZfCaigou():
    """
    """
    def __init__(self):
        super(ZfCaigou, self).__init__()
        # 实际地址
        self.url = 'http://www.zjzfcg.gov.cn/purchaseNotice/index.html?categoryId=3001'
        self.driver = webdriver.Chrome()
        self.wait = WebDriverWait(self.driver, 30)  # 设置超时时间
        self.zoom = 1

    def open(self):
        self.driver.get(self.url)
        self.driver.maximize_window()
        time.sleep(5)
        i = 0
        while i < 8:
            self.driver.find_element_by_css_selector('div.paginationjs-pages > ul > li.paginationjs-next.J-paginationjs-next a').click()
            i += 1

        time.sleep(3)


if __name__ == '__main__':
    z = ZfCaigou()
    z.open()

这样做的确可以实现动态页面的加载。



那怎样实现页面跳转后的信息加载呢?
整合上面对的两者的代码即可,将第一个练习的代码加到第二个练习的while后面就可以实现了

# -*- coding: utf-8 -*-
# @AuThor  : frank_lee

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import time
from scrapy.selector import Selector


class ZfCaigou():
    """
    """
    def __init__(self):
        self.url = 'http://www.zjzfcg.gov.cn/purchaseNotice/index.html?categoryId=3001'
        self.driver = webdriver.Chrome()
        self.wait = WebDriverWait(self.driver, 30)  # 设置超时时间
        self.zoom = 1

    def get_info(self):
        self.driver.get(self.url)
        self.driver.maximize_window()
        time.sleep(5)
        i = 0
        while i < 8:  #这里的页数随意设置,也可以定义一个total_page,然后在这里用self.total_page调用
            time.sleep(2)
            data = self.driver.page_source
            response = Selector(text=data)  # 这里如果不使用"text=data",直接写data将会报错 'str' object has no attribute 'text'
            infodata = response.css(".items p")
            for infoline in infodata:
                city = infoline.css(".warning::text").extract()[0].replace("[", "").replace("·", "").strip()
                issuescate = infoline.css(".warning .limit::text").extract()[0]
                title = infoline.css("a .underline::text").extract()[0].replace("]", "")
                publish_date = infoline.css(".time::text").extract()[0].replace("[", "").replace("]", "")
                print(city + "--" + title + "--" + issuescate + "--" + publish_date)
            self.driver.find_element_by_css_selector(
                'div.paginationjs-pages > ul > li.paginationjs-next.J-paginationjs-next a').click()
            i += 1
            time.sleep(3)
        time.sleep(3)
        self.driver.close()


if __name__ == '__main__':
    z = ZfCaigou()
    z.get_info()

自己想要的信息已抓取到,接下来将其保存到数据库。

1.保存到MongoDB数据库

在初始化函数中加入:

# 以下保存到MongoDB数据库,不想要可以删掉
self.client = pymongo.MongoClient(host="localhost", port=27017)
self.db = self.client['zfcaigou']
# MongoDB部分结束

在get_info函数for语句中加入:

# 为保存到MongoDB做的处理,不想保存可以删掉
result = {
    "city": city,
    "issuescate": issuescate,
    "title": title,
    "publish_date": publish_date,
}
self.save_to_mongo(result)
# 结束

再写一个自定义函数:

def save_to_mongo(self, result):
    if self.db['caigou'].insert(result):
        print("保存成功啦,嘻嘻")

超简单有木有,然后看着满满的“保存成功”,开心!


2.保存到mysql数据库

在初始化函数中加入:

# 以下保存到Mysql数据库,不想要可以删掉
self.db = pymysql.connect("localhost", "root", "", "test")
self.cursor = self.db.cursor()
# 创建一个表
sql = """create table  caigou (
  city varchar(30) not null ,
  issuescate varchar(30) not null,
  title varchar(200) not null,
  publish_date varchar(50) not null
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"""
try:
    # 执行sql语句
    self.cursor.execute(sql)
    # 提交到数据库执行
    self.db.commit()
except:
    # 如果发生错误则回滚
    self.db.rollback()
# mysql部分结束

在get_info函数for语句中加入:

# 保存到mysql数据库的操作,可选
insert_sql = """
    insert into caigou(city, issuescate, title, publish_date) values(%s, %s, %s, %s);
    """
result = {
    "city": city,
    "issuescate": issuescate,
    "title": title,
    "publish_date": publish_date
}
try:
    # 执行sql语句
    self.cursor.execute(insert_sql, (result["city"], result["issuescate"], result["title"], result["publish_date"]))
    # 提交到数据库执行
    self.db.commit()
except:
    # 如果发生错误则回滚
    self.db.rollback()

这样只要能连接到mysql,一切都自动化了,以前保守的做法是在本地建表,python代码写sql插入语句,此次练习增加了建表语句。


数据插入成功,(#^.^#)。

3.保存到redis数据库

在初始化函数中加入:

self.pool = redis.ConnectionPool(host='localhost', port=6379)  
self.myredis = redis.Redis(connection_pool=self.pool)
self.keyName = 'ZfCaigou'

在for循环中加入:

self.myredis.lpush(self.keyName, json.dumps(result))

需要注意的是,以上想要保存数据到某个数据库,需要首先打开对应的服务器。或者对应的可视化工具能够连接上,然后才能指望数据能够成功保存。

详细代码请参考:https://github.com/hfxjd9527/caigou

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,094评论 4 62
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,097评论 1 32
  • 模糊是时间的一层纱 走一秒,它就在格子上清晰一格 人性是模糊的格子 每当清晰一格我们都看清这格仔处于什么颜色 什么...
    苦咖啡小奶油阅读 185评论 0 0
  • 小云出生在上个世纪九十年代的苏北一个普通家庭,父母都是按部就班的上班族,虽然不是很富足,但是也是不愁吃不愁喝的。小...
    徐老巫婆阅读 466评论 1 6
  • 今天我的朋友圈转爆了一篇文,名字叫《罗振宇的骗局》,一看就是标题党写出来赚流量的,因为好奇,我还是点进去了,...
    漂漂美妞妞阅读 7,492评论 0 0