Python爬虫

Python爬虫

爬虫前基础了解

本质:模拟浏览器打开网页、获取网页中我们想要的那部分数据
**准备工作:**通过浏览器分析目标网页
获取数据:
通过http库向目标站点发起请求,请求可以包含额外的leader等信息,如果服务器能正常响应,会得到一个Response,便是所要获取的页面内容
解析内容:
得到的内容可能是html、json等格式,可以用页面解析库、正则表达式等进行解析
保存数据:
保存形式多样。可以存为文本、也可以保存到数据库、或者保存特定格式的文件

编码规范
一般Python程序的第一行需要加入
#--coding:utf-8 --或者 # coding=utf-8
这样可以在代码中包含中文

python文件可以加入main函数用于测试程序
if__name__ == “main”:
这个程序会从冒号后面开始,使程序按照自己组织的顺序来

  • import bs4 #网页解析、获取数据
  • import re #正则表达式、进行文字匹配
  • import urllib.request,urllib.error #制定url,获取网页数据
  • import xlwt #进行excel操作
  • import sqlite3 #进行sqlite数据库操作

文件位置表示方法

“./”: 表示当前文件夹的位置
“.\”:表示文件系统里的位置(为了转义加了\)
r"":不用转义,直接复制电脑里面的地址

获取数据

python一般使用urllib库获取页面

获取一个get请求

![
复制在文本文档里打开就是百度网页

获取一个post请求(一般用在模拟用户登录)

http://httpbin.org 测试网址
在这里插入图片描述

超时处理

在访问网页超时时,采取行动结束访问,先去做别的事情。这里可以配合异常处理使用。
timeout 限时在多长时间内未响应便执行except里面捕获到超时错误里的内容。

要模拟一个从网页上去登录的样子,我们可以选择一个浏览器打开,点击F12,选择Network,刷新网页,点击暂停,在第一条线那里获取我们的User-Agent.

模拟从谷歌浏览器的百度网页访问豆瓣
在这里插入图片描述在这里插入图片描述

BeautifulSoup4

将复杂HTML文档转换成一个复杂的树型结构,每个节点都是Python对象,所有对象可以归纳为4种:Tag、NavigableString、BeautifulSoup、Comment

Tag

标签及其内容:拿到它所找到的第一个内容
在这里插入图片描述

NavigableString

获得标签里面的内容,不包括标签头部和尾部

print(bs.title.string)
print(bs.a.atters) #将a标签里面的所有属性以字典的方式打印出来、有利于之后很好的取出想要的数据

BeautifulSoup

表示整个文档,即bs

Comment

是一个特殊的NavigableString,输出的内容不包含注释符号

文档的遍历

from bs4 import BeautifulSoup
file = open("./baidu.html", "rb")  # rb:readbyte
html = file.read().decode('utf-8')
bs = BeautifulSoup(html, "html.parser")
print(bs.title)
print(bs.title.string)
print(bs.a)  # 找到的第一个出现的这种标签里的所有内容
print(bs.a.attr)
print(type(bs.head))
print(type(bs.a.attrs))
# Tag的.content属性可以将tag的子节点以列表的方式输出
print(bs.head.contents)
# 用列表的索引来获取它的某一个元素

print(bs.head.contents[1])children:获取Tag的所有子节点,返回一个生成器

for child in bs.body.children:
    print(child)

在这里插入图片描述

文档的搜索

from bs4 import BeautifulSoup
file = open("./baidu.html", "rb")  # rb:readbyte
html = file.read().decode('utf-8')
bs = BeautifulSoup(html, "html.parser")
# 字符串过滤:会查找与字符串完全匹配的内容
import re
t_list = bs.find_all("a")
# print(t_list)
# 正则表达式搜索:使用search()方法来匹配内容
t_list = bs.find_all(re.compile("a"))  # 只要标签里含有a就会全部输出,比如<head>

# print(t_list)

# 方法:传入一个函数(方法),根据函数的要求来搜索
def name_is_exists(tag):  # 传一个标签,返回这里面的属性值
    return tag.has_attr('name')  # 判断对象是否包含对应的属性

t_list = bs.find_all(name_is_exists)  # bs就是传入函数name_is_exists()里的参数
# kwargs 参数
t_list = bs.find_all(id="head")
t_list = bs.find_all(class_=True)  # class是关键字,不能直接使用
# for item in t_list:
#     print(item)
# text参数
t_list = bs.find_all(text="hao123")
t_list = bs.find_all(text=["hao123", "地图", "贴吧"])
t_list = bs.find_all(text=re.compile("\d"))  # 应用正则表达式来查找包含特定文本发内容(标签里字符串) \d表示数字
# for item in t_list:
#     print(item)
# limit 参数  获取多少条该标签的内容
t_list = bs.find_all("a", limit=3)
# for item in t_list:
#     print(item)
# css选择器
t_list = bs.select('title')  # 通过标签来查找
t_list = bs.select('.mnav')  # 通过类名来查找(加点的是类名class的内容)
t_list = bs.select('#u1')  # 通过id来查找(加#的是id的内容)
t_list = bs.select('a[class="bri"]')  # 通过属性来查找
t_list = bs.select("head > meta>link")  # 通过子标签来查找
t_list = bs.select(".mnav ~ .bri")  # 通过兄弟标签来查找 ~符号表示兄弟标签
print(t_list[0].get_text()) #拿到第一个元素的文本
for item in t_list:
    print(item)

正则表达式 re

判断字符串是否符合一定标准

# 正则表达式:字符串模式 (判断字符串是否符合一定的标准)
import re
# 1、创建模式对象
pat = re.compile('AA')  # 这里的AA,是正则表达式,用来验证其他的字符串
# search方法:进行比对查找
m = pat.search('CBA')  # search字符串被校验的内容
m = pat.search('ABCAA')  # 只会检测到第一个匹配的字符
print(m)
# 没有模式对象
m = re.search("asd", "Aasd")  # 前面的字符串是规则,后面的字符串是被校验的对象
print(m)
print(re.findall("a", "ADSADADDa"))  # 前面的字符串是规则(正则表达式),后面的字符串是被校验的对象
print(re.findall("[A-Z]", "ADSADADDa"))
print(re.findall("[A-Z]+", "ADSaDADDa"))
# sub()  替换
print(re.sub("a", "A", "abcdcasd"))  # 找到a用A替换
# 建议在正则表达式中,被比较的字符串前面加上r,不用担心转义字符的问题
a = r"\aabd-\'"
print(a)

正则表达式的常用操作符

在这里插入图片描述

?问号还有一个一样:表示非贪婪模式 即 只查找匹配模式的第一个字符串
如正则表达式 \S+c 匹配字符串aaaacaaaaaaac的结果是aaaacaaaaaaac,而\S+?c则会优先匹配aaaac

\s代表正则表达式中的一个空白字符(可能是空格、制表符、其他空白)
在这里插入图片描述

re库的主要功能函数

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

保存数据

excel表存储

利用python库xlwt将抽取的数据datalists写入excel表格.
在这里插入图片描述

完整代码

爬虫豆瓣Top250

# coding = utf-8
from bs4 import BeautifulSoup
import re
import urllib.request, urllib.error
import xlwt
import sqlite3


def main():
    baseurl = "https://movie.douban.com/top250?start="
    # 获取数据
    datalist = getData(baseurl)
    savepath = "豆瓣电影Top250.xls"
    # 保存数据
    saveData(datalist, savepath)
    # askURL('https://movie.douban.com/top250?start=')


# 创建正则表达式对象,表示规则  ?问好表示非贪婪模式 即只会找到符合模式的第一个字符串
findLink = re.compile(r'<a href="(.*?)">')  # 33行
# 影片图片的链接
findImgSrc = re.compile(r'img.*src="(.*?)"', re.S)  # re.S忽略换行符
# 影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')
# 影片评分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
# 影片评价
findJudge = re.compile(r'<span>(\d.*)</span>')
# 影片概况
findInq = re.compile(r'<span class="inq">(.*)</span>')
# 找到影片的相关内容
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)


# 爬取网页
def getData(baseurl):
    datalist = []
    for i in range(0, 10):  # 调用获取页面信息的函数10次
        url = baseurl + str(i * 25)
        html = askURL(url)  # 保存获取到的网页源码
        # 逐一解析数据
        soup = BeautifulSoup(html, "html.parser")
        for item in soup.find_all('div', class_="item"):  # 查找符合要求的字符串,形成列表
            # print(item)

            data = []
            # 保存电影信息
            item = str(item)
            # 获取影片详情的链接
            link = re.findall(findLink, item)[0]  # 通过正则表达式查找指定的字符串
            data.append(link)
            imgSrc = re.findall(findImgSrc, item)[0]
            data.append(imgSrc)
            titles = re.findall(findTitle, item)
            if len(titles)==2:
                ctitle = titles[0]  # 添加中文名
                data.append(ctitle)
                otitle = titles[1].replace("/", "")  # 去掉多余的/符号
                data.append(otitle) # 添加外文名
            else:
                data.append(titles[0])
                data.append(' ')  # 外文名留空
            rating = re.findall(findRating, item)[0]  # 添加评分
            data.append(rating)
            judgeNum = re.findall(findJudge, item)[0]  # 添加评价人数
            data.append(judgeNum)
            inq = re.findall(findInq, item)  # 添加概述
            if len(inq) != 0:
                inq = inq[0].replace("。", "")  # 去掉句号
                data.append(inq)
            else:
                data.append(" ")  # 留空
            bd = re.findall(findBd, item)[0]
            bd = re.sub('<br(\s+)?/>(\s+)?', " ", bd)  # 去掉<br/>
            bd = re.sub('/', " ", bd)  # 替换/
            data.append(bd.strip())  # 去掉前后的空格

            datalist.append(data)  # 把处理好的一部电影信息放入datalist

    # print(datalist)

    return datalist


# 得到指定一个URL的网页内容
def askURL(url):
    head = {  # 模拟浏览器头部信息,向豆瓣服务器发送消息
        "User-Agent": "Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit /"
                      " 537.36(KHTML, likeGecko) Chrome / 88.0.4324.190 Safari / 537.36"
        # 用户代理,表示告诉豆瓣服务器,我们是什么类型的机器的浏览器(本质上是告诉浏览器,我们可以接收什么水平的文件内容)
    }
    request = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
        # print(html)
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)  # 打印错误的码
        if hasattr(e, "reason"):
            print(e.reason)  # 打印错误的原因
    return html


# 保存数据
def saveData(datalist, savepath):
    book = xlwt.Workbook(encoding='utf-8')  # 创建workbook对象
    sheet = book.add_sheet('豆瓣电影TOP250', cell_overwrite_ok=True)  # 创建工作表 参数cell_overwrite_ok=True, 可以覆盖原单元格中数据
    col = ('电影详情链接', "图片链接", "影片中文名", "影片外文名", "评分", "评价数", "概况", "相关信息")
    for i in range(0, 8):
        sheet.write(0, i, col[i])  # 写入列名
    for i in range(0, 250):
        print("第%d条" % (i+1))
        data = datalist[i]
        for j in range(0, 8):
            sheet.write(i+1, j, data[j])  # 数据

    book.save(savepath)  # 保存数据表


if __name__ == "__main__":
    main()
    print("爬取完毕!")
   

爬虫微博weibo

# coding = utf-8
from bs4 import BeautifulSoup
import re
import urllib.request, urllib.error
import xlwt
import time
import sqlite3


def main():
    baseurl = "https://d.weibo.com/102803_ctg1_4288_-_ctg1_4288?from=faxian_hot&mod=fenlei#"
    # 获取数据
    m, datalist = getData(baseurl)
    savepath = "weibo.xls"
    # 保存数据
    saveData(datalist, savepath, m)
    # askURL('https://movie.douban.com/top250?start=')


# 影片图片的链接
findtxt = re.compile(r'>.*?<', re.S)


# 爬取网页
def getData(baseurl):
    datalist = []
    datalist2 = []
    num = 0
    num2 = 0
    for i in range(0, 10):  # 调用获取页面信息的函数100次
        url = baseurl + str(i)
        html = askURL(url)  # 保存获取到的网页源码
        # 逐一解析数据
        soup = BeautifulSoup(html, "html.parser")

        for item in soup.find_all('div', class_="WB_text W_f14"):  # 查找符合要求的字符串,形成列表
            # print(item["nick-name"])

            data = []
            # # 保存电影信息
            item = str(item)
            txt = re.findall(findtxt, item)
            for i in txt:
                if ">\'][\'<" in i:
                    continue
                if ">:<" in i:
                    continue
                if ">回复<" in i:
                    continue
                if "><" in i:
                    continue
                if ">\', \'<" in i:
                    continue
                #     if "@" in i:
                #         continue
                if "> <" in i:
                    continue
                # if "展开全文c" in i:
                #     continue
                # if "c" in i:
                #     continue

                else:
                    data.append(i)
            subTextHead = re.compile(">")
            subTextFoot = re.compile("<")

            m = []

            for lastResult in data:
                resultExcel1 = re.sub(subTextHead, '', lastResult)
                resultExcel = re.sub(subTextFoot, '', resultExcel1)
                # print(i, resultExcel)
                m.append(resultExcel)

            n = "".join(m)
            num += 1
            datalist.append(n)




    # print(datalist,'\n')
    return num, datalist


# 得到指定一个URL的网页内容
def askURL(url):
    head = {  # 模拟浏览器头部信息,向豆瓣服务器发送消息
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
        "Cookie": "_T_WM=195ffb1e4f4d79574bf5fd53075f159c; SUB=_2A25NTp6DDeRhGeBM7FcY-SzKzT2IHXVusCLLrDV6PUJbkdANLUzRkW1NRNFu5Zfj1XVQl-wrxUaYGvuVn_L1hviX; SCF=AkZHVDGhzSxxLcw5odEDchdZ5rOAyiDY5Jkyp8sFGOi97Tc-EZi0tb71Jhp1zEbJs3GixyPGzd1olsFPt2t3Qb4.; SSOLoginState=1615523539"}
    request = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8", "ignore")
        # print(html)
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)  # 打印错误的码
        if hasattr(e, "reason"):
            print(e.reason)  # 打印错误的原因
    return html


# 保存数据
def saveData(datalist, savepath, m):
    book = xlwt.Workbook(encoding='utf-8')  # 创建workbook对象
    sheet1 = book.add_sheet('带标签', cell_overwrite_ok=True)  # 创建工作表 参数cell_overwrite_ok=True, 可以覆盖原单元格中数据
    sheet2 = book.add_sheet('不带标签', cell_overwrite_ok=True)  # 创建工作表 参数cell_overwrite_ok=True, 可以覆盖原单元格中数据
    col = ('序号', "微博内容")
    for i in range(0, 2):
        sheet1.write(0, i, col[i])  # 写入列名

    for i in range(0, m):
        print("第%d条" % (i + 1))
        data1 = datalist[i]
        # print(data1)
        for j in range(0, 2):
            sheet1.write(i + 1, 0, i + 1)
            sheet1.write(i + 1, j, data1)  # 数据


    book.save(savepath)  # 保存数据表


if __name__ == "__main__":
    star = time.time()
    main()
    end = time.time()
    print('running time: %s Seconds' % (end - star))
    print("爬取完毕!")

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值