我个人的思路是往数据分析的方向走,那么作为数据分析,首先得有数据,爬虫就是一个很好的获取数据的方式。于是我决定先花一部分时间学会爬虫,再学习数据分析。这样才能避免只能做书中的习题,而没办法自己动手做数据分析项目。

这次选用的教材是哔哩哔哩上的视频《Python爬虫基础5天速成》,之前已经看过两节视频了。感觉讲的还是蛮细致的,就继续听下去吧。

先放一下听那两节课的代码纪要:

# -*- coding: utf-8 -*-
import urllib.request
import urllib.parse
import gzip
# 获取一个get请求
#rss = urllib.request.urlopen("http://ailibili.com")
# print(rss.read().decode('utf-8'))

# # 获取post请求
# data = bytes(urllib.parse.urlencode({'123':'321'}),encoding='utf-8')
# ess = urllib.request.urlopen("http://httpbin.org/post",data=data)
# print(ess.read().decode('utf-8'))

# # 获取get请求及超时
# ess = urllib.request.urlopen("http://httpbin.org/get",timeout=3)
# print(ess.read().decode('utf-8'))
#
# ess = urllib.request.urlopen("http://ailibili.com")
# print(ess.getheaders())


def ungzip(data):
    try:
        data = gzip.decompress(data)
    except BaseException:
        pass
    return data


url = "https://www.douban.com"
headers = {
    "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",


}
req = urllib.request.Request(url=url, headers=headers)
rep = urllib.request.urlopen(req)
sss = rep.read().decode("utf-8")
print(ungzip(sss))

这里特别要注意两个地方,首先爬取的豆瓣首页的代码是gzip加密的,需要解压。def ungzip的代码块就是解压的。

其次这个代码建议在python3.9及以上版本中使用,在使用3.8版本的时候有可能会出现以下错误:

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certi

那么,咱们就继续:

错误集:

from bs4 import BeautifulSoup
import urllib.request
import urllib.error

def main():
    baseurl = "https://movie.douban.com/top250?start=0"
    # 1.爬取网页
    datalist = getdata(baseurl)
    savepath = ".\\豆瓣电影top250.xls"
    # 3.保存数据
    # savedata(savepath)
    askurl("https://movie.douban.com/top250?start=0")

# 爬取网页
def getdata(baserurl):
    datalist = []
    # 2.逐一解析数据
    return datalist



# 得到指定一个URL的网页信息
def askurl(url):
    # 模拟浏览器头部信息,向豆瓣服务器发送消息
    head = {
        # 用户代理,告诉网站服务器,我们是什么类型的机器、浏览器(本质上告诉浏览器,我们可以接收什么水平的文件)
        "User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 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)




# 3.保存数据
def savedata(savepath):
    pass

main()

这里如果没有加上尾巴的main(),就会不显示任何结果,因为没有调用主函数。

from bs4 import BeautifulSoup
import urllib.request
import urllib.error

def main():
    baseurl = "https://movie.douban.com/top250?start="
    # 1.爬取网页
    datalist = getdata(baseurl)
    savepath = ".\\豆瓣电影top250.xls"
    # 3.保存数据
    # savedata(savepath)
    askurl("https://movie.douban.com/top250?start=")

# 爬取网页
def getdata(baserurl):
    datalist = []
    for i in range(0,10): #调用获取页面信息的函数,共10次
        url = baserurl +str(i*25)
        html = askurl(url)  # 保存获取到的网页原码
    # 2.逐一解析数据
    return datalist



# 得到指定一个URL的网页信息
def askurl(url):
    # 模拟浏览器头部信息,向豆瓣服务器发送消息
    head = {
        # 用户代理,告诉网站服务器,我们是什么类型的机器、浏览器(本质上告诉浏览器,我们可以接收什么水平的文件)
        "User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 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



# 3.保存数据
def savedata(savepath):
    pass

main()

到这里,其实我有点迷惑,return到底有啥用?看了网上很多回答,返回值。

但是什么时候返回,返回哪个值,不是很清楚。

其实我对def或者是class中的互相调用到现在还是迷迷糊糊的。

或许这就是小学时期遇到了自己不懂的知识点,到了初中后就迎刃而解了吧。

1.bs4的Beautifulsoup用法:查找第一个对应标签及其包含的内容

from bs4 import BeautifulSoup
file = open('./python中return到底什么意思? - 知乎.html')
ss = file.read()
bs = BeautifulSoup(ss,"html.parser")
print(bs.a)

bs.title.string = 只打印内容,不打印标签(字符串)

bs.a.attrs = 标签内的所有属性值

bs = 整个文档

bs.a.string = 是一个特殊的navigalbestring 输出的内容不包含注释符号

bs.head.contents = 遍历文档中的head(也可以替换成别的),并形成列表,可使用列表下标。其中head是大标签,contents是小标签。也就是从head里查找contents。

t_list = bs.find_all(“a”) = 查找文档内所有的‘a’标签及内容。 #字符串过滤,与字符串完全匹配的内容

t_list = bs.find_all(re.compile(“a”)) #正则表达式:search()方法来匹配内容:

def name _is _exists(tag): #通过方法来进行查询

return tag.has_attr(“name”)

t_list = bs.find_all(name _is _exists)

t_list = bs.find_all(id=”head”) #通过参数,查找标签下的内容。比如此函数就是查找文档里所有含有id=‘head’标签及其内容。

t_list = bs.find_all(class_ = “True”) # 查找包含class的内容及其标签下的内容。

t_list = bs.find_all(text = “知乎”) #查找文档内所有完全匹配’知乎’两个字的内容。(可能用来查重吧?)

t_list = bs.find_all(text = re.compile(“\d”)) #应用正则表达式查找特定文本的内容(标签里的字符串)

t_list = bs.find_all(“a”,limit=3) #limit用来控制你最多能获得多少个符合要求的内容,本条里为获取三条。

t_list = bs.select(‘title’) #通过标签来查找

t_list = bs.select(‘.mnav’) #通过类名来查找,比如class = ‘mnav’

t_list = bs.select(‘u1’) #通过id来查找,比如id=u1

t_list = bs.select(‘a[class=”bri”]’) #通过属性来查找

t_list = bs.select(“head > title”) #通过子标签来查找,比如查找head标签下的tilte内容。

t_list = bs.select(“.mnav ~ .bri”) #通过兄弟标签来查找,比如查找跟.mnav同级的.bri下的内容。

print(cs[0].get_text()) #获取列表位置为[0]的文本信息

正则表达式内容:





import re
# 创建模式对象
pat = re.compile("AA") # 此处的"AA"为正则表达式,用来去验证其他的字符串
m = pat.search("AVAVAA") # search字符串被校验的内容,进行比对查找
print(m)
import re
# 创建模式对象
m = re.search("asd","asddds") #前面的字符串是规则,后面的字符串是被校验的对象
print(m)
import re
# 创建模式对象
m = re.findall("a","ASDAadsa") # 前面字符串是规则(正则表达式),后面字符串是被校验的字符串
print(m)
import re
# 创建模式对象
m = re.findall("[a-z]+","ASDAadsa") # 前面字符串是规则(正则表达式),后面字符串是被校验的字符串
print(m)
import re

print(re.sub("a","A",r"\n/nbcdabcd")) # 在字符串"abcdabcd"中查到a用A替换

# 建议在正则表达式中,被比较的字符串前面加上r。不用担心转译字符的问题。
from bs4 import BeautifulSoup
import urllib.request
import urllib.error
import re


def main():

    # 1.爬取网页
    baseurl = "https://movie.douban.com/top250?start="
    datalist = getdata(baseurl)
    savepath = ".\\豆瓣电影top250.xls"
    # 3.保存数据
    # savedata(savepath)


findlink = re.compile(r'<a href="(.*?)">')  # 创建正则表达式对象,表示规则(字符串的模式)
findtitle = re.compile(r'<span class="title">(.*?)</span>')  # 创建电影名的正则表达式
findothertitle = re.compile(r'<span class="title">(.*?)</span>') # 创建电影原名的正则表达式
findother = re.compile(r'<span class="other">\xa0/\xa0(.*?)</span>') # 创建电影其他译名的正则表达式
findxinxi = re.compile(r'<p class="">\n(.*?)</p>',re.S) # 创建电影其他信息的正则表达式
findstar = re.compile(r'<span class="rating_num" property="v:average">(.*?)</span>') # 创建电影评分的正则表达式
findinq = re.compile(r'<span class="inq">(.*?)</span>') #创建电影一句话说明正则表达式
findjudge = re.compile(r'<span>(\d*)人评价</span>') # 创建电影多少人评价正则表达式
findimgsrc = re.compile(r'<img .* src="(.*?)"',re.S)  # 创建电影封面的正则表达式


# 爬取网页


def getdata(baseurl):
    datalist = []
    for i in range(0, 1):  # 调用获取页面信息的函数,共10次
        url = baseurl + str(i * 25)
        html = askurl(url)  # 保存获取到的网页原码
        # 2.逐一解析数据
        soup = BeautifulSoup(html, "html.parser")
        for item in soup.find_all('div', class_='item'):  # 查找符合要求的字符串,形成列表
            # print(item) # 测试:查看电影item全部信息
            data = []  # 保存一部电影的所有信息
            item = str(item)
            try:
                title = re.findall(findtitle, item)[0]
                data.append(title)
                for i in re.findall(findothertitle, item):
                    i = i.replace("\xa0", "").replace("/", "").replace("\xa0", "")
                    if i != data[0]:
                      data.append(i)
                other = re.findall(findother, item)[0].replace("/","\xa0/\xa0").replace("\xa0/\xa0", "")
                data.append(other)
                link = re.findall(findlink, item)[0]  # re库用来通过正则表达式查找指定的字符串
                data.append(link)
                imgsrc = re.findall(findimgsrc, item)[0]
                data.append(imgsrc)
                xinxi = re.findall(findxinxi, item)[0].replace("\xa0","").replace("\n","").replace("<br/>","")

                data.append(xinxi)
                star = re.findall(findstar,item)[0]
                data.append(star)
                inq = re.findall(findinq,item)[0]
                data.append(inq)
                judge = re.findall(findjudge,item)[0]
                data.append(judge)

                print(data)
            except IndexError:
                data.append(" ")



    return datalist


# 得到指定一个URL的网页信息
def askurl(url):
    # 模拟浏览器头部信息,向豆瓣服务器发送消息
    head = {
        # 用户代理,告诉网站服务器,我们是什么类型的机器、浏览器(本质上告诉浏览器,我们可以接收什么水平的文件)
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 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


# 3.保存数据
def savedata(savepath):
    pass


main()

到这里为止,基本上数据就爬取完毕了,下面就是数据分析的部分了。那么下次再见吧。

胭惜雨

2021年3月8日

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据