目录
一、爬虫与爬虫的合法性
python爬虫可能人尽皆知,但是爬虫具体是干什么的,用我自己的话表述就是将数据拿出来方便自己使用,这里的数据就指的是互联网上的资源,像百度网站上公开的信息你都可以获取到。爬虫通常有三种方法:正则表达式、bs4和xpath
这里就要牵扯到爬虫的合法性,我觉得在现阶段的学习中,你可以爬取到的数据都是在后台有所显示的,所以不会存在不合法的问题,爬虫存在的目的就是为了方便你可以更快的把这些数据拿出来并且整合到一起,像之前学爬虫看到了好多梗说“爬虫学的好,牢饭吃到饱”。我应该还没有到那样高水平的地步吧hh。
二、requests模块
在写爬虫之前,我们先来了解一些关键的步骤,上面说了,你要拿到互联网上的一些资源,你必须要打开网页才行,假如我要爬取百度资源,我就要先在我的编译器中打开百度再进行操作,requess模块的功能就在于此,我们可以通过requests来实现python对http请求的操作。我们先来看下面一个小的爬虫(资源1day)
import requests
url = "http://www.baidu.com"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
}
response = requests.get(url=url,headers=headers)
page_text = response.text
with open("my_baidu.html",mode = "w",encoding="utf-8") as f:
f.write(page_text) #读取到网页的源代码
print("over")
用requests.get()方法就可以获取一个网址,然后用response.text获取网址内容,最后把东西写入到你的文件夹里。这就是一个小爬虫,爬取了百度的初始页面
在这里还有一个问题我们发现我们使用了headers={},这就是一个简单的反爬措施,使得爬虫伪装起来,伪装成一个浏览器,header在哪里找呢,打开你用的浏览器页面的检查,在网络里随便打开一个名称,在最底部就可以找到
三、前端知识介绍
爬虫爬取内容的时候,需要一些前端知识。你会发现,页面也是人写出来的,是通过各种html、 css、js等语法写出来的,我们看到的页面的所有内容,都可以再一个地方中看到,这时你只需要打开页面点击右键打开检查或者检查页面源代码,就可以看到页面的源代码,页面中的所有内容都可以在里面找到。我们爬取的内容也是需要从这里面去找的。
关于有关的前端知识,我的博客里有关于html的详解,详情请见html基础_hxiaogang2021的博客-CSDN博客
四、客户端渲染和服务器渲染
爬虫里这个概念是特别特别重要的两个概念,甚至你每次爬取数据都会用得到
1.服务器渲染 在服务器那边直接把数据和html整合在一起,统一返回浏览器 在页面原代码可以看到数据 2.客户端渲染 第一次请求只要一个html框架,第二次请求拿到数据,进行数据展示(要数据) 在页面源代码中看不到数据
举个例子再有的页面中,页面源代码会直接把你所需要的数据显示出来,你可以直接爬取,这就是服务器渲染,而有的数据在你打开有关页面后,会有一个链接,又跳转到另一个页面,这时爬取数据的时候就需要使用两次或者更多的爬虫去一步一步爬取数据。
五、正则表达式
在python基础我们都学过正则表达式,其实正则表达式也就是一种较为繁琐的方法了,正则表达式我个人的一些总结也在我的资源里
在页面源代码中,你会发现有好多标签,而这些标签都是不需要的,我们需要的就是里面的文字,使用我们需要使用正则表达式把文字提取出来,我们在这里爬取的是豆瓣电影TOP250的电影名称。
分析发现,我们在页面源代码里面可以看到电影名都在li标签的后面并以span标签结尾,我们就可以用正则表达式中华的.*?来将文字提取出来(2day)
import requests
import re
url = "https://movie.douban.com/top250"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
}
resp = requests.get(url,headers = headers)
# print(resp.text) #检查反爬
page_content = resp.text
#解析数据
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>',re.S)
result = obj.finditer(page_content)
for i in result:
print(i.group("name"))
通过这样的方法,我们不仅可以将里面的名子提取出来,还可以将里面的拍摄年份,评分和观看人数都可以爬取出来,并且还可以将爬取到的东西写入到excel文件里
import requests
import re
import csv
url = "https://movie.douban.com/top250"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
}
resp = requests.get(url,headers = headers)
page_content = resp.text
#解析数据
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)'
r'</span>.*?<p class="">.*?<br>.*?(?P<year>.*?) .*?<span '
r'class="rating_num" property="v:average">(?P<score>.*?)</span>.*?'
r'<span>(?P<number>.*?)人评价</span>',re.S)
result = obj.finditer(page_content)
f = open("3.1day.csv",mode="w",encoding="gbk",newline="")
csvwriter = csv.writer(f)
for it in result:
dic = it.groupdict()
dic["year"] = dic["year"].strip()
csvwriter.writerow(dic.values())
f.close()
print("over")
六、BS4
在使用bs4的时候也要下载一个模块叫bs4,可以在bs4中调用一个方法叫beautifulsoup
我们知道页面都是由前端的各种标签和内容组成的,bs4就是可以通过定位到标签内容来爬取到数据,原理就是实例化一个BeatifulSoup对象,将页面源代码加入到该对象中,调用BeautifulSoup的方法定进行标签定位和提取数据
bs4方法
soup.TageName | 返回的是第一次出现的tagname对应的标签 |
---|---|
soup.find("div") | 同上 |
soup.find("div",class_ = "song") | 属性定位 |
soup.find_all("div") | 返回所有的div标签 返回的是一个列表 |
soup.select(" > ") | >表示一个层级 |
soup.select(".tang>ul a") | .表示上一级 空格表示多个层级 |
获取标签中的文本数据
soup.a.text/string/get_text() | |
soup.select(".tang>ul a")[0].text() | |
text/get_text() 获取全部的内容 | |
string 获得直系的内容 |
实例
这里爬取的是三国演义各章的标题和内容爬取出来(3day)
https://www.shicimingju.com/book/sanguoyanyi.html
我们发现通过属性定位以后,标题的名字全都是在li标签下的,通过属性名>ul>li(标签名)就可以定位
import requests
from bs4 import BeautifulSoup
url = "https://www.shicimingju.com/book/sanguoyanyi.html"
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55"
}
page_text = requests.get(url=url,headers=headers).text
#实例化BeatifulSoup对象,将页面源代码数据加载到该对象中
soup = BeautifulSoup(page_text,"lxml")
#定位内容标签
li_list = soup.select(".book-mulu > ul > li")
fp = open("sanguo","w",encoding="utf-8-sig",errors="ignore")
for i in li_list:
title = i.a.string
但是这样之后我们发现了一个问题,我们取到的a标签并不能爬取到三国演义的内容,这就出现了之前说的客户端渲染,我们必须再对href中的详情页再发起一次请求,来解析出章节的内容
for i in li_list:
title = i.a.string
#详情页的网址 用拼接的方法
detail_url = "https://www.shicimingju.com/" + i.a["href"]
#对详情页发起请求
detail_page_text = requests.get(url=detail_url,headers=headers).text.encode("ISO-8859-1")
detail_soup = BeautifulSoup(detail_page_text,"lxml")
#在详情页中发起定位
div_tag = detail_soup.find("div",class_="chapter_content")
content = div_tag.text
fp.write(title + ":" + content + "/n")
print(title,"over")
这样就可以将爬取的内容全部写入到我们之前创建的文件里面
七、xpath
xpath是我们最常用且最便捷高效的一种解析方式
xpath的使用需要下载一个lxml的模块,在lxml中实例化一个etree的对象,且需要将被解析的对象的页面源码数据加载到该对象中,之后调用etree对象中的xpath表达式实现标签的定位和内容的捕获
xpath表达式
从根节点开始定位 表示一个层级 | / |
表示多个层级,从任意位置定位 | // |
属性定位 | //div[@class="song"] tag[@attrname="attrvalue"] |
索引定位 | //div[@class="song"]/p[3] |
取文本 | /../../text()[0] 获取直系的 |
获取的非直系的所有的文本内容 | //text() |
取属性 | //div/img/@attrname //img/scr |
实例
抓取百度美女图片(4day)
#导入模块
import requests
import os
from lxml import etree
url = 'https://pic.netbian.com/4kmeinv/' #获取页面网址
#简单的反爬,使用headers将爬虫伪装起来
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
response = requests.get(url=url,headers=headers)#使用request.get方法获取html页面
page_text = response.text #获取html页面中的文本内容
tree = etree.HTML(page_text) #调用HTML类对HTML文本进行初始化,成功构造XPath解析对象
#利用os模块创建文件
if not os.path.exists("F:\python\爬虫\debug"):
os.mkdir("F:\python\爬虫\debug")
前面的requests请求都是一样的,不同的在于tree = etree.HTML(page_text) 在这里是实例化了一个etree对象,将需要被解析的页面源代码加载到该对象中。
我们还导入了os模块创建文件,检查该文件夹下是否有此文件,有则保留,没有则创建,里面所有的文件路径均为我自己的文件路径
之后调用xpath方法进行定位,我们从最后一个div标签开始定位 到ul标签再到li标签
li_list = tree.xpath('//div[@class="slist"]/ul/li')
for li in li_list :
img_src = 'http://pic.netbian.com' + li.xpath('./a/img/@src')[0] #在li标签下再次定位到图片
img_name = li.xpath('./a/img/@alt')[0] + 'jpg'
img_name = img_name.encode('iso-8859-1').decode('gbk') #获取图片名称
img_data = requests.get(url=img_src,headers=headers).content #爬取图片
img_path ='F:\\python\\爬虫\\debug\\'+img_name #获取图片路径
with open(img_path,'wb') as fp: #将爬取到的图片写入文件夹
fp.write(img_data)
print(img_name,'over')
最后在利用写入文件的办法,就可以把爬取到的文件写入到之前创建的文件夹里
八、总结
在学习了一学期python结课之后,我的课程设计就是爬取百度图片,就是利用的最后的xpath爬取的,我觉得python的爬虫也是比较有趣同样也是比较难的,后面的内容也需要大量的经历去学习,我觉得这篇讲的也很一般,学习爬虫需要的东西很多,后面也会对一些单独的内容展开讲述,也希望大家指正问题。