Python学习24

python—简单的数据抓取一(简单的文字数据抓取(认识cookie)、简单的图片抓取)

学习目标:

python —数据抓取以及相关事项


学习内容:

1、简单的文字数据抓取(认识cookie、小说简介、小说内容、京东商品信息)
2、简单的图片数据抓取

1、简单的文字数据抓取

1、cookie的认识

  • session机制采用的是在服务端保持状态的方案,而cookie机制则是在客户端保持状态的方案,cookie又叫会话跟踪机制
  • 常见的是持久cookie:当我们在网站中,首次访问或者登陆就会生成cookie,即便跳转页面或者关闭浏览器再打开你依然是登陆状态
  • cookie的集中常见属性:document.cookie=“key=value;expires=失效时间;path=路径;secure;(secure表安全级别)”
    常见的cookie生成:用户名生成、用户IP生成、匿名生成(方便服务器传递一些信息)

2、获取页面源码的简单方法

  • 注意获取网页内容的编码方式
import requests
import re
source = requests.get("https://www.23us.com/").content.decode('gbk')
demo = re.compile('<p class="ul1">\[(.*?)\]《<a class="poptext" href=".*?" target="_blank">(.*?)</a>》<\/p><p class="ul2"><a href=".*?" target="_blank">(.*?)</a></p><p>(.*?)</p>(.*?)</li>')
lists = demo.findall(source)
print(lists)
输出:
[('其他类型', '电影系统逍遥游', '第931章 佩恩来袭', '渔歌飘渺', '01-20'), ('都市言情', '都市极品医神', '第5212章 叶辰的布局!(八更!求月票!)', '风会笑', '01-20'), ('玄幻魔法', '八符', '第二百四十八章 弹指间灰飞烟灭', '噬君', '01-20'), ('玄幻魔法', '凡神物语', '第542章 重构', '商城', '01-20'), ('其他类型', '大明元辅', '第180章 税改大幕拉开', '云无风', '01-20'), ('历史军事', '朝为田舍郎', '第四百七十七章 潼关换将', '贼眉鼠眼', '01-20'), ('玄幻魔法', '灵龙传奇', '第461章:争先恐后', '悲伤的牧羊人', '01-20'), ('都市言情', '我有一个大世界', '第五百七十章 送快递的', '沉入太平洋', '01-20'), ('网游动漫', '英雄联盟之兼职主播', '第1423章 一改常态的SZ', '永远的黄昏', '01-20'), ('其他类型', '篮坛之锋芒逼人', '770开会开会开会!未知更动人!', '爱吃鱼的芒果', '01-20'), ('武侠修真', '最强昆仑掌门', '第一千零九十二章 观音泪与鬼泣剑', '阅读能力', '01-20'), ('其他类型', '我有一座八卦炉', '第七四二章 我李靖不死,你休想踏入陈塘关半步', '雪人不吃素', '01-20'), ('都市言情', '当医生遇上不正经系', '594、丧心病狂', '魔鬼藤', '01-20'), ('都市言情', '重生之跨国巨头', '第八百三十四章 后摩尔时代的芯片行业', '地球不安静', '01-20'), ('其他类型', '氪金剑仙李太白', '第210章 新罗北斗剑宗', '蜀山徐公', '01-20'), ('其他类型', '戏闹初唐', '第二五三二章', '活着就', '01-20'), ('其他类型', '平成骑士的旅行', '第511章 所有异虫都由我打倒!', '滴滴咯', '01-20'), ('历史军事', '无敌升级王', '第3671章 谈一谈', '可爱内内', '01-20'), ('玄幻魔法', '巅峰仙道', '第一千六百五十章 突破第三阵(二更)', '寒梅惊雪', '01-20'), ('其他类型', '皇天战尊', '第八百三十二章 暗衣剑客', '策马笑天下', '01-20'), ('其他类型', '我有一群地球玩家', '第一千四百八十五章:牧云姬的选择(下)', '第七个魔方', '01-20'), ('其他类型', '快穿之专业打脸指南', '第一千七百四十二章 牛皮吹破天之后5', '凤栖桐', '01-20'), ('其他类型', '都市极品医神', '第一千七百一十一章 安心去吧', '十万伏特', '01-20'), ('武侠修真', '一世符仙', '第一千二百零八章 解决', '玉菩提', '01-20'), ('其他类型', '绝世靓仔', '第五百九十二章天晴雨停你又行?', '纳肉', '01-20'), ('都市言情', '无敌神婿', '第三百四十五章 你有血光之灾', '小生水蓝色', '01-20'), ('网游动漫', '网游三国之真实世界', '第三百二十章 初战边章', '又又果子', '01-20'), ('其他类型', '天官之路', '第643章 现在的我已经完全不是以前的我', '戴铃铛的老猫', '01-20'), ('其他类型', '游戏王者', '第五十五章 战纪灵(上)', '伍玥初柒', '01-20'), ('历史军事', '汉世祖', '第38章 湖南无战事', '芈黍离', '01-20')]

 

3、获取的数据入mysql库

  • 在mysql库建立相关字段的数据表
  • 引入python的mysql相关的包
  • 建立连接
  • 遍历获取的数据依次入库

在这里插入图片描述

import requests
import re
# 引mysql包
import pymysql 
# 建立mysql连接
connects = pymysql.connect(database='zhuaqu', user='root', password='1234', host='127.0.0.1', charset='utf8')
cursor = connects.cursor()

source = requests.get("https://www.23us.com/").content.decode('gbk')
demo = re.compile('<p class="ul1">\[(.*?)\]《<a class="poptext" href=".*?" target="_blank">(.*?)</a>》<\/p><p class="ul2"><a href=".*?" target="_blank">(.*?)</a></p><p>(.*?)</p>(.*?)</li>')
lists = demo.findall(source)
print(lists)
# 遍历数据并依次入库
for a, b, c, d, e in lists:
    sql = 'insert into books(types,bookname,new_chapter,author,update_time) values("{}","{}","{}","{}","{}")'.format(a, b, c, d, e)
   # 执行sql语句
    cursor.execute(sql)
    #向mysql提交数据
    connects.commit()
connects.close()

 

 

4、抓取小说内容并导入到本地文件

  • 根据网页链接样式决定抓取方式
    总的章节在这里插入图片描述
    点进每个章节
    在这里插入图片描述
  • 所以需要在总章节获取到所有章节的地址,然后再分别获取各个章节里面的内容

在总的章节页面内每个tr标签分为四个td标签需要获取td中的每章的链接
在这里插入图片描述
获取到每章的连接之后,再分别获取章节名在h1标签中和章节内容在dd标签中
在这里插入图片描述

import requests
import re
# 获取到总章节的页面
source = requests.get('https://www.23us.com/html/72/72982/').content.decode('gbk')
# 正则匹配到每章节的地址
demo = re.compile('<a href="(\d+\.html)">.*?</a>')
lists = demo.findall(source)
# 遍历列表中每个章节的地址
for i in lists:
    # 把每章节的地址加到网址的后面,以便直接获取到每章的内容
    hrefs = 'https://www.23us.com/html/72/72982/'+i
    source1 = requests.get(hrefs).content.decode('gbk')
    # 正则匹配每章章名和文字内容
    demo = re.compile('<h1>(.*?)</h1>.*?<dd id="contents".*?>(.*?)</dd>', re.S)
    lists = demo.findall(source1)
    # 匹配的章名和文字在列表中为两个元素a,b
    print(lists)
    for a, b in lists:
        # 指定写入文件的地址,后面的yyt.txt实际对于代码而言不是文件,只是匹配内容写入的地址
        op = open('F:\\yyt.txt', 'a+')
        # 替换掉文字中的&nbsp;和<br />特殊字符
        b = b.replace('&nbsp;', ' ').replace('<br />', '\n')
        # 用\n换行来分开章节名和章节内容
        op.write('\n'+a+'\n'+b)
        op.close()

 

5、抓取京东的商品信息

  • 京东的页面信息其实是两页的信息,抓取只能抓一页的数据,暂时改变url的放式抓取到一整页(即page=1,和page=2)的信息
import requests
import re
import pymysql
from lxml import etree
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
connectes = pymysql.connect(database='zhuaqu', user='root', password='1234', host='127.0.0.1', charset='utf8')
cursor = connectes.cursor()
for i in range(3, 5):
    # 将i转化为字符串
    j = str(i)
    a = 'https://search.jd.com/Search?keyword=大地瓜&qrst=1&stock=1&page=P&s=57&click=0'
    # 用sub将i的值替换到page=P处
    b = re.sub('P', j, a)
    source = requests.get(b, headers=headers).text
    base = etree.HTML(source).xpath('// *[ @ id = "J_goodsList"] / ul / li')
    for i in base:
        price = i.xpath('div / div[2] / strong/i/text()')
        goods_name = i.xpath(' div / div[3] / a / em/text()')
        dian = i.xpath('div / div[5] / span / a/text()')
        # 将数据存入数据库
        sql = 'insert into goods(price, goods_name, goods_dian ) value ("{}", "{}", "{}")'.format(price, goods_name, dian)
        # 用ping命令在每次传输之前测试与数据库的连通性
        connectes.ping(reconnect=True)
        cursor.execute(sql)
        connectes.commit()
        connectes.close()

 


2、简单的图片数据抓取

1、利用xpath抓取分组的图片
在这里插入图片描述
抓取图片时用到了xpath:

  • 用xpath读取到了整个图片组的展示页面的xpath://*[@id="home"]
  • 用xpath读取到了第一组图片组的xpath://*[@id="home"]/div/div[2]/a[1]
  • 用xpath读取到了第一组图片组标题的xpath://*[@id="home"]/div/div[2]/a[1]/div[1]/text()
  • 用xpath读取到了第一组第一张图片的xpath://*[@id="home"]/div/div[2]/a[1]/div[2]/div[1]
  • 可以注意到a之前的都为公共部分,a[1]、a[2]…分别指第一组和第二组图片组://*[@id="home"]/div/div[2]/a
import requests
import re
# 用xpath时引用的包
from lxml import etree
# 在系统创建文件夹时引用的包
import os
# 去除特殊字符时引用的包
from string import punctuation
# 利用header头部模仿浏览器访问网站
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
#设置遍历出的page网站翻页
for page in range(1,6):
    # 获取到网站第二页的数据
    source = requests.get('https://www.doutula.com/article/list/?page='+str(page), headers=headers).text
    # 提取出获取图组时xpath的公共部分
    base = etree.HTML(source).xpath('//*[@id="home"]/div/div[2]/a')
    # 在base中取出每一组图片组
    for b in base:
        # 利用图片组获取到图片具体位置
        pic = b.xpath('div[2]/div/img/@data-original')
        # 利用图片组获取到图片组标题
        title = b.xpath('div[1]/text()')[0]
        # 去除title的特殊字符
        title = re.sub('\W', '', title)

        # 判断该文件夹是否存在
        if os.path.isdir(title):
            pass
        else:
            # 不存在就创建这个文件夹
            os.mkdir(title)

        # 判断是有图片的链接
        if len(pic) != 0:
            # 遍历图片的链接
            for img in pic:
                # 根据下划线拆分图片的连接取最后一段就是图片的名字(http://img.doutula.com/production/uploads/image/2017/10/17/20171017455259_KEfwXW.jpg)
                pic_name = img.split('_')[-1]
                # 访问并读取遍历到的图片
                pic_content = requests.get(img, headers=headers).content
                # 将读取到的图片分别存入创建的对应文件及里
                op = open(title+'/'+pic_name, 'wb')
                # 写入读取的文件
                op.write(pic_content)
                op.close()

 

2、利用xpath抓取单张图片

import requests
import re
from lxml import etree
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
source = requests.get('https://www.doutula.com/article/list/?page=2', headers=headers).text
base = etree.HTML(source).xpath('//*[@id="home"]/div/div[2]/a[1]/div[2]/div[1]/img/@data-original')
# 注意此处读取第一组图片时,在相同的字段@data-original有四个读取的结果属于列表,所以应取出第一个元素为第一张图片
pic = requests.get(base[0], headers=headers).content

op = open('F:\\pycharm\\lx\\1.gpj', 'wb')
op.write(pic)
op.close()
posted @ 2021-01-26 16:45  MFTang  阅读(77)  评论(0编辑  收藏  举报