python-爬虫(最后附爬取数据的源码)

爬虫初识

什么是爬虫?

  1. 网络爬虫,是一种按照一定规则,自动抓取互联网信息的程序或者脚本。由于互联网数据的多样性和资源的有限性,根据用户需求定向抓取相关网页并分析已成为如今主流的爬取策略。
  2. 只要能通过浏览器访问的数据都可以通过爬虫抓取。
  3. 爬虫的本质:模拟浏览器打开网页,获取网页中我们想要的那部分数据。

1. 获取数据

python一般使用urllib2获取页面数据

import urllib.request

# 获取一个get请求
response = urllib.request.urlopen("https://www.baidu.com/")
print(response.read().decode("utf-8") # 获取到的网页资源进行utf-8解码

# 获取一个post请求
import urllib.parse
data = bytes(urllib.parse.urlencode({"hello":"world"},encoding = "utf-8"))
response = urllib.request.urlopen("http://httpbin.org/post",data = data)
print(response.read())


# 超时处理
try:
   response = urllib.request.urlopen("http://httpbin.org/get",timeout=0.01)
   print(response.read().decode("utf-8"))
except urllib.error.URLError as e:
   print("time out!")

# 获取请求状态
response = urllib.request.urlopen("https://www.baidu.com/")
print(response.status())

# 将代理更改为模拟浏览器访问
 head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
        # 模拟浏览器头部信息
    }
    request = urllib.request.Request(url, headers=head)

2. 解析数据

通过导入from bs4 import BeautifulSoup

from  bs4 import  BeautifulSoup

# 打开html文件(可以自定义,但一般都是抓取的页面信息进行解析)
file = open("./文件名.html")
html = file.read()
# 通过html.parser 解析器解析网页数据,给到bs对象
bs = BeautifulSoup(html,"html.parser")
# bs对象存储网页标签元素及其内容(之能拿到找到的第一个内容),以下打印的是title标签中包含的内容 1.Tag 标签及其内容
print(bs.title)

# .string帮助拿到标签中的内容 2.通过type(bs.title.string),得到类型为NavigableString
print(bs.title.string)

# .attrs拿到该标签下的所有属性,并以键值对(字典)的方式表示
print(bs.a.attrs)

# 3.BeautifulSoup类型,拿到网页所有元素
print(bs)

# 4.Comment  是一个特殊的NavigableString 输出内容不包含注释符号

2.1 遍历文档树

  1. .contents :获取Tag的所有子节点,返回一个list
# tag的.content 属性可以将tag的子节点以列表的方式输出
print(bs.head.content)
# 用列表索引来获取它的某一个元素
print(bs.head.content[1])

  1. children : 获取tag所有子节点返回一个生成器
for child in bs.body.children:
    print(child)

2.2文档搜索

# 1.find_all() 
# 通过find_all()方法找到所有的a标签:字符串过滤,会查找到与字符串完全匹配的内容
t_list = bs.find_all(a)
print(t_list)


# 正则表达式搜索,使用search()方法来匹配内容
t_list = bs.find_all(re.compile("a")) # 查询到列表标签包含a字符串的内容
print(t_list)



# 方法:传入一个函数(方法),根据函数的要求来搜索
def name_is_exists(tag):
    return tag.has_attr("name") #找到元素包含name属性的标签
t_list = bs.find_all(name_is_exists)
print(t_list)



# 2. Kwargs 参数:指定参数进行搜索
t_list = bs.find_all(id="head") # 查询属性id 等于head 的内容

t_list = bs.find_all(class_=True) # 打印标签包含class属性的内容


# 3. text 参数
t_list= bs.find_all(text="hao123")  #打印结果为 hao123

t_list= bs.find_all(text= re.compile("/d")) # 通过正则表达式打印出所有文本内容带数字的内容

# 4.limit 参数 控制输出的个数
t_list= bs.find_all("a",limit=3) # 找到html中前三个带a标签的内容


# 5.css选择器
t_list= bs.select('title')  # 通过标签来查找
t_list= bs.select('.类名')  # 通过类名
t_list= bs.select('id') # 通过id
t_list= bs.select("a[class = 名字]") # 查找a标签中 class= 名字 的内容
t_list= bs.select("head > title") # 找到父标签head下的子标签 title

t_list= bs.select(".类名1 ~ .类名2") # 找到.类名1 的兄弟标签.类名2
# 打印兄弟标签的内容
print(t_list[0].get_test())

# 通过for循环打印出来的内容更易阅读
for item in t_list:
    print(t_list)
    

2.3 正则表达式

通用,且常用的正则表达式

操作符 说明 实例
. 表示任何单个字符
[ ] 字符集,对单个字符给出取值范围 [abc] 表示a、b、c,[a-z]表示a到z单个字符
[^ ] 非字符集,对单个字符u给出排除范围 [^abc] 非a或b或c的单个字符
* 前一个字符0次或无限次扩展 abc* 表示 ab、abc、abcc、abccc等
+ 前一个字符1次或无限次扩展 abc+ 表示abc、abcc、abccc等
? 前一个字符0次或1次扩展 abc? 表示ab、abc
左右表达式任意一个 abd丨def 表示abc、def
“左闭右开”是指区间不包括左边的内容,但是涵盖右边的内容。
操作符 说明 实例
{m} 扩展前一个字符m次 ab{2}c 表示abbc,ab{3}c 表示abbbc
{m,n} 扩展前一个字符m至n次(含n) ab{1,2} c 表示abc、abbc
^ 匹配字符串开头 ^abc 表示abc且在一个字符串的开头
$ 匹配字符串结尾 abc$ 表示abc且在一个字符串的结尾
( ) 分组标记,内部只能使用丨操作符 (abc)表示abc,(abc丨def)表示abc、def
\d 数字,等价于[0-9]
\w 单词字符,等价于[A-Za-z0-9] 表示A到Z,a到z,数字0到9

Import re
导入的re库的主要功能函数

函数 说明
re.search() 在字符串中搜索匹配正则表达式的第一个位置,返回match对象
re.match() 从一个字符串的开始位置起匹配正则表达式,返回match对像
re.findall() 搜索字符串,以列表类型返回全部能匹配的子串
re.split() 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
re.finditer() 搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
re.sub() 在一个字符串中替换所有匹配正则表达式的字串,返回替换后的字符串

3. 数据存储

3.1 数据存储–excel

import xlwt
# 创建workbook 对象
workbook = xlwt.Workbook(encoding="utf-8")

# 创建工作表
worksheet = workbook.add_sheet('sheet1')
# 例: 存入九九乘法表
for i in range(1, 10):
    for j in range(1, i+1):
        worksheet.write(i-1, j-1, "%d * %d = %d" % (i, j, i*j))
# 保存数据表
workbook.save('student.xls')

3.2 数据存储–SQLite

(后期补上)

4. 交流学习

python-爬虫(最后附爬取数据的源码)_第1张图片

5. 爬取源码

from bs4 import BeautifulSoup  # 网页解析,获取数据
import re  # 正则表达式,进行文字匹配
import urllib.request, urllib.error  # 指定URL, 获取网页数据
import xlwt  # 进行excel操作
import sqlite3  # 进行SQLite进行数据库的操作


def main():
    # 获取网页链接
    base_url = "https://movie.***(某电影网站).com/top250?start="
    # 1.爬取网页
    datalist = getData(base_url)

    savePath = "某电影电影top250.xls"
    # 3.保存数据
    saveData(savePath, datalist)


# 创建正则表达式对象,表示规则(字符串模式)
# 影片详情链接规则
findLink = re.compile(r'') 
# 影片图片
findImgSrc = re.compile(r'', re.S)  # re.S 让换行符包含在字符中
# 影片片名
findTitle = re.compile(r'(.*)')
# 影片评分
findRating = re.compile(r'(.*)')
# 评价人数
findJudge = re.compile(r'(\d*)人评价')
# 概况
findInq = re.compile(r'(.*)')
# 找到影片的相关内容
findBd = re.compile(r'

(.*?)

'
, re.S) # 1.爬取网页 def getData(base_url): datalist = [] for i in range(0, 10): # 调用获取页面信息的函数10次 url = base_url + str(i * 25) # 为参数start赋值 html = askURL(url) # 获取到的一页html,返回给到html对象 # 2.逐一解析数据(在爬取页面时就直接解析,而不是爬取所有在解析) # 解析器:html.parser 解析html soup = BeautifulSoup(html, "html.parser") # 查找网页所有的内容,取标签为div 属性为item的div for item in soup.find_all("div", class_="item"): data = [] # 保存一部电影的所有信息 item = str(item) # 转成字符串 # 比较规则为findLink 从item里面找出符合findlink规则的内容取第一个符合条件的 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: # 添加中文名 chinese_title = titles[0] data.append(chinese_title) # 添加外文名 .replace("/", "") 将字符/ 用空值代替 foreign_title = titles[1].replace("/", "") data.append(foreign_title) 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: inq1 = inq[0].replace("。", "") data.append(inq1) else: data.append(' ') # 电影相关内容 bd = re.findall(findBd, item)[0] # 将bd 对象中的
标签
bd = re.sub(r'(\s+)?', "", bd) # 替换\ bd = re.sub('/', " ", bd) # 去掉前后空格 data.append(bd.strip()) datalist.append(data) print(datalist) return datalist # 3.保存数据 def saveData(savePath, datalist): # 创建workbook 对象 book = xlwt.Workbook(encoding="utf-8", style_compression=0) # 创建工作表 sheet = book.add_sheet('某电影Top250', 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)) # 取datalist中的第i条数据存入data对象 data = datalist[i] for j in range(0, 8): # 将data中的第一条数据 存成8列 sheet.write(i+1, j, data[j]) # 保存数据表 book.save(savePath) # 得到一个指定URL的网页内容(一共250 条,需要爬取25个页面) def askURL(url): # User - Agent 告诉豆瓣服务器,我们是什么类型的机器 head = { "User-Agent": "Mozilla/ 5.0(Windows NT 10.0;Win64; x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 96.0.4664.93Safari / 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() print("爬取完毕")

你可能感兴趣的:(Python,python,爬虫,开发语言)