Python 爬虫学习笔记


Python 爬虫笔记

为了学习机器学习时方便获取数据以及日后的web开发

这个寒假又开始捡起爬虫(其实之前只会基本请求,网页源码全扒下来的那种~~)

准备工作

准备爬取豆瓣top250的信息

规律:每页都是以25为间隔

利用Chrome开发者工具辅助

需要引入的库:

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

代码架构如下:

def main():                                                                    
    baseUrl="https://movie.douban.com/top250"       #基本网址                      

    # 爬取网页                                                                     
    savePath=r".\豆瓣电影Top250.xls"                                               
    # 逐一解析数据                                                                   
    # 保存数据                                                                     

# 爬取网页                                                                         
def getData():                                                                 
    datalist=[]                                                                

    # 逐一解析数据                                                                   
    return datalist                                                            
def SaveData(savePath):                                                        
    print()                                                                    


if __name__=="__main__":                                                       
    main()                                                                     

urlib用法

import urllib.request

#获取一个get方式
response=urllib.request.urlopen("https://www.baidu.com")
#将网页打开并返回网页数据,就是获得了网页源代码
print(response.read().decode('utf-8'))#打印信息,并且保证中文显示
import urllib.request
import urllib.parse#解析器
#获取一个post请求
data=bytes(urllib.parse.urlencode({"hellow":"world"}),encoding="utf-8")#转化二进制,解析键值对
response=urllib.request.urlopen(r"https://httpbin.org/post",data=data)
print(response.read().decode("utf-8"))
# 返回如下:
# {
#   "args": {},
#   "data": "",
#   "files": {},
#   "form": {
#     "hellow": "world"这里是我们请求的数据
#   },
#   "headers": {
#     "Accept-Encoding": "identity",
#     "Content-Length": "12",
#     "Content-Type": "application/x-www-form-urlencoded",
#     "Host": "httpbin.org",
#     "User-Agent": "Python-urllib/3.7",
#     "X-Amzn-Trace-Id": "Root=1-60102159-645571fd5c4c09b93338b8d5"
#   },
#   "json": null,
#   "origin": "117.65.146.144",
#   "url": "https://httpbin.org/post"
# }
import urllib.request
import urllib.parse#解析器
#超时
try:
    response=urllib.request.urlopen(r"https://httpbin.org",timeout=0.01)
    print(response.read())
except urllib.error.URLError as e:
    print("超时了")
import urllib.request
import urllib.parse#解析器

response=urllib.request.urlopen(r"https://douban.com")
print(response.status)
#urllib.error.HTTPError: HTTP Error 418: 
#表示发现你是一个爬虫了
print(response.getheaders())
#获取响应头,
print(response.getheader('Set-Cookie'))
#获取具体的头部数据

如何让网页不知道我们是爬虫从而避免418:

import urllib.request
import urllib.parse#解析器

url="https://douban.com"
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
}
#网页检查network中从header中复制粘贴来的,
req=urllib.request.Request(url=url,headers=headers)
response=urllib.request.urlopen(req)
print(response.read().decode("utf-8"))
#成功返回了

编写函数来访问:

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


def main():
    baseUrl = "https://movie.douban.com/top250"  # 基本网址
    AskUrl(baseUrl)


#得到指定URL的内容
def AskUrl(url):
    head = {#模拟浏览器头部信息
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 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)


if __name__ == '__main__':
    main()

这里逐页获取:

def main():
    baseUrl = "https://movie.douban.com/top250?start="  # 基本网址

    # 爬取网页                                                                     
    savePath = r".\豆瓣电影Top250.xls"
    # 逐一解析数据                                                                   
    # 保存数据                                                                     
    getData()


# 爬取网页
def getData():
    datalist = []
    for i in range(0,10):
        url=baseurl+str(i*25)
        html=AskUrl(url) #保存获取到的源码
        # 逐一解析数据
    return datalist

#得到指定URL的内容
def AskUrl(url):
    head = {#模拟浏览器头部信息
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 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


if __name__ == "__main__":
    main()                                                                     

BeautifulSoup用法

BS4可以将文档归档四种类型:

  • tag
  • navigaableString
  • beautifulsoup
  • comment

具体用法

from bs4 import BeautifulSoup

bs=BeautifulSoup(html,"html.parser")
#解析文件树
print(bs.a)
print(bs.title)
print(bs.header)
#这种方式访问标签内容,默认只拿到第一个内容
#1.tag及其内容



print(bs.title.string)
#只知道标签内容,
#2.navigableString标签里面的内容

print(bs.a.atters)
#拿到标签内部超链接以及标签内部的样式名称

#获得整个文档内容
print(bs)#整个文档
print(bs.name)#document
print(bs.attrs)#{}
#3BeautifulSoup


print(ba.a.string)
#这里拿到源码的注释的内容。没有注释的符号




#文档的遍历
#采用下标访问
print(bs.head.contents[1])

#文档的搜索
#字符串过滤
t_list=bs.find_all("a")#查找所有a标签
print(bs.t_list)

#正则表达式搜索
import re
t_list=bs.find_all(re.compile("a"))#包含a字母的标签

#传入一个函数,根据一个函数搜索
def name_is_exists(tag):
    return tag.has_atter("name")#包含name的标签,作为了解

t_list=bs.find_all((name_is_exists))


#kwargs参数搜索
t_list=bs.find_all(id="head")#含有id=header的标签中所有内容
t_list=bs.find_all(class_=True)#含有clas的标签以及子内容
t_list=bs.find_all(href="http://baidu.com")#含有此链接的标签
t_list=bs.find_all(text=["百度","贴吧"])#3文本参数搜索,将会搜索出文本
t_list=bs.find_all(text=re.compile("\d"))#用正则表达式搜索特点文本内容(标签内字符串)

#limit参数
t_list=bs.find_all("a",limit=3)#限定搜索三个

#css选择器
t_list=bs.select("title")#通过标签查找
t_list=bs.select(".class")#类名查找
t_list=bs.select("#id")#id查找
t_list=bs.select("head>title")#查找子标签
t_list=bs.select("。mnav~.bri")#查找兄弟标签

print(t_list[0].get_text())#找到标签包含的文本内容

开始爬取

import re
from bs4 import BeautifulSoup
import urllib.request
import xlwt

findLink=re.compile(r'<a href="(.*?)">')
findImg=re.compile(r'<img.*src="(.*?)"',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 main():
    baseUrl = "https://movie.douban.com/top250?start="  # 基本网址

    # 爬取网页
    savePath = r".\豆瓣电影Top250.xls"
    # 逐一解析数据
    # 保存数据
    datalist=getData(baseUrl)



# 爬取网页
def getData(baseUrl):
    datalist = []
    for i in range(0,10):
        url=baseUrl+str(i*25)
        html=AskUrl(url) #保存获取到的源码
        # 逐一解析数据
        soup=BeautifulSoup(html,"html.parser")
        for i in soup.find_all('div',class_="item"):#查找目标内容
            # print(i) 测试查看全部信息
            data=[]
            i=str(i)
            link=re.findall(findLink,i)[0]
            data.append(link)
            ImgSrc=re.findall(findImg,i)
            data.append(ImgSrc)
            titles=re.findall(findTitle,i)
            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,i)[0]#评分
            data.append(rating)
            judgeNumber=re.findall(findJudge,i)[0]
            data.append(judgeNumber)#评价人数
            inq=re.findall(findInq,i)
            if len(inq)!=0:
                inq=inq[0].replace("。",'')#去掉句号
            else:
                inq="暂无简介"
            data.append(inq)#但是不是每一部都有概述
            bd=re.findall(findBd,i)[0]
            bd=re.sub('<br(\s+)?>(\s+)?'," ",bd)#去掉br
            bd=re.sub('/',"—",bd)
            data.append(bd.strip())#去掉前后空格
            datalist.append(data)#处理好的信息放入列表
    print(datalist)
    return datalist

#得到指定URL的内容
def AskUrl(url):
    head = &#123;#模拟浏览器头部信息
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
    &#125;#用户代理,告诉豆瓣我们可以接受什么类型的文件内容,这里一定要用豆瓣网页的
    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


if __name__ == "__main__":
    main()

保存数据

xlwt用法

import xlwt

workbook=xlwt.Workbook(encoding="utf-8")#创建workbook对象
worksheet=workbook.add_sheet('sheet1')#创建工作表
worksheet.write(0,0,"hellow")#向第一个元素写入hellow第一个是行,第二个个是列
workbook.save("表格.xls")

参考1

参考2

案例:写入九九乘法表

import xlwt

workbook=xlwt.Workbook(encoding="utf-8")#创建workbook对象
worksheet=workbook.add_sheet('sheet1')#创建工作表
for i in range(9):
    for j in range(i+1):
        worksheet.write(i,j,"%d * %d = %d"%(i+1,j+1,(i+1)*(j+1)))
workbook.save("表格.xls")

爬取数据写入

import re
from bs4 import BeautifulSoup
import urllib.request
import xlwt

findLink=re.compile(r'<a href="(.*?)">')
findImg=re.compile(r'<img.*src="(.*?)"',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 main():
    baseUrl = "https://movie.douban.com/top250?start="  # 基本网址

    # 爬取网页
    savePath = r"豆瓣电影Top250.xls"
    # 逐一解析数据
    # 保存数据
    datalist=getData(baseUrl)
    SaveData(datalist,savePath)


# 爬取网页
def getData(baseUrl):
    datalist = []
    for i in range(0,10):
        url=baseUrl+str(i*25)
        html=AskUrl(url) #保存获取到的源码
        # 逐一解析数据
        soup=BeautifulSoup(html,"html.parser")
        for i in soup.find_all('div',class_="item"):#查找目标内容
            # print(i) 测试查看全部信息
            data=[]
            i=str(i)
            link=re.findall(findLink,i)[0]
            data.append(link)
            ImgSrc=re.findall(findImg,i)
            data.append(ImgSrc)
            titles=re.findall(findTitle,i)
            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,i)[0]#评分
            data.append(rating)
            judgeNumber=re.findall(findJudge,i)[0]
            data.append(judgeNumber)#评价人数
            inq=re.findall(findInq,i)
            if len(inq)!=0:
                inq=inq[0].replace("。",'')#去掉句号
            else:
                inq="暂无简介"
            data.append(inq)#但是不是每一部都有概述
            bd=re.findall(findBd,i)[0]
            bd=re.sub('<br(\s+)?>(\s+)?'," ",bd)#去掉br
            bd=re.sub('/',"—",bd)
            data.append(bd.strip())#去掉前后空格
            datalist.append(data)#处理好的信息放入列表
    print(datalist)
    return datalist

#得到指定URL的内容
def AskUrl(url):
    head = &#123;#模拟浏览器头部信息
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
    &#125;#用户代理,告诉豆瓣我们可以接受什么类型的文件内容,这里一定要用豆瓣网页的
    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):
    film = xlwt.Workbook(encoding="utf-8",style_compression=0)  # 创建workbook对象
    filmSheet = film.add_sheet('豆瓣电影250',cell_overwrite_ok=True)  # 创建工作表 覆盖以前内容
    col=("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息")
    for i in range(8):
        filmSheet.write(0,i,col[i])#写入第一行
    for i in range(250):
        print("第%d条"%i)
        data=datalist[i]
        for j in range(8):
            filmSheet.write(i+1,j,data[j])

    film.save(savePath) #保存


if __name__ == "__main__":
    main()

效果如下:

最终效果图

至此基本的网页爬取技巧结束了,关于爬虫更加深入的引用后面会补充


文章作者: 晓沐
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 晓沐 !
评论
 上一篇
蓝桥杯Python算法训练 蓝桥杯Python算法训练
蓝桥杯Python组算法训练1 题目 1017: [编程入门]完数的判断 时间限制: 1Sec 内存限制: 128MB 提交: 23074 解决: 10991 题目描述 一个数如果恰好等于不包含它本身所有因子之和,这个数就称为”完数”。 例
2021-03-18 晓沐
下一篇 
神经网络与深度学习练习 神经网络与深度学习练习
神经网络与深度学习作业大垃圾一年没写python辣(其实去年也学的稀烂),今年要机器学习不得不捡起py开始学 为了逐步把自己的算法水平移植到py上,于是决定开始Py恢复训练(其实就是重新学) 然后这个笔记主要是存放西安科技大学的神经网络与深
2021-01-19
  目录