01 爬虫入门

一. Python初识

一些简单概念

Python中没有数组的概念

列表[]

1
2
3
可以存储元素: abc=[“My”, “You”]
如果要选取列表中的元素 abc[1] 输出 ‘You’
要替换列表中的元素: abc[1]=”He”

元祖()

1
2
Cde=(“My”, “You”)
选取元素同样用 cde[1]

列表和元组的区别

列表中的元素是可以修改的 但是元组这种数据类型呢 是不能修改的

集合

1
2
3
parame = {value01,value02,...}
或者
set(value)

字典

1
d = {key1 : value1, key2 : value2 }

简单代码展示

函数的使用

1
2
3
4
5
6
7
8
9
10
11
12
def abc():
print("abcd!")

def function1(a,b):
if(a>b):
print(a)
else:
print(b)

function1(10,19)

abc()

模块

1
2
3
4
5
import data_05functiondefinition

data=data_05functiondefinition.function1(19,10)

print(data)

文件写入

1
2
3
4
5
fh = open("/Users/biandudu/Desktop/PythonDataAnalysis/file1.txt","w")
contents1 = "我是文件内容"
fh.write(contents1)

fh.close()

文件读取

1
2
3
4
5
6
7
8
9
10
11
fh1 = open("/Users/biandudu/Desktop/PythonDataAnalysis/file2.txt","r")
# data2 = fh1.read()
# print(data2)

while True:
line = fh1.readline()
if len(line)==0:
break
print(line)

fh1.close()

异常抛出

1
2
3
4
5
6
7
# 中间异常不处理,会导致程序的崩溃
try:
print("my")
printasa("sss")
except Exception as err:
print(err)
print("hello")

作业

作业一:输出乘法口诀

1
2
3
4
5
for i in range(1,10):
for j in range(1,i+1):
print(str(i)+"*"+str(j)+"="+str(i*j)+" ",end="")
# end=""意思是末尾不换行,加空格
print()

作业二:将多个Excel表格内容合并

思路

可以采用一些操作Excel的模块来实现,比如xlrd、xlwt、openyxl、xlsxwriter等模块。xlrd模块主要用于读取Excel表,xlwt与xlsxwriter模块主要用于将数据写入表中,两个模块任选其一即可,但是xlwt与xlsxwriter模块不支持修改表,所以在信息追加的时候会较麻烦,其实这个问题至少有两种思路解决:

A、换成其他模块,比如openpyxl等,这个模块实现起来会相对简单一些

B、仍然使用xlwt与xlsxwriter等模块,但是先将每次读取的信息存储到list(列表)中,然后,最后一次写入。这一种方式稍微复杂一些

此外,还有一个难点,即一个表格中有多个sheet,我们希望能够用程序自动获取这多个sheet,然后将各sheet中的内容一并写入到最终表格中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import xlrd,xlsxwriter
#设置要合并的所有文件
allxls=["F:/第一个测试文件.xls","F:/第二个测试文件.xls","F:/第三个测试文件.xls"]
#设置合并到的文件
endxls ="F:/endxls.xls"

#打开表格
def open_xls(file):
try:
fh=xlrd.open_workbook(file)
return fh
except Exception as e:
print(str("打开出错,错误为:"+e))

#获取所有sheet
def getsheet(fh):
return fh.sheets()

#读取某个sheet的行数
def getnrows(fh,sheet):
table=fh.sheets()[sheet]
content=table.nrows
return content

#读取某个文件的内容并返回所有行的值
def getfilect(fh,fl,shnum):
fh=open_xls(fl)
table=fh.sheet_by_name(shname[shnum])
num=getnrows(fh,shnum)
lenrvalue=len(rvalue)
for row in range(0,num):
rdata=table.row_values(row)
rvalue.append(rdata)
#print(rvalue[lenrvalue:])
filevalue.append(rvalue[lenrvalue:])
return filevalue

#存储所有读取的结果
filevalue=[]
#存储一个标签的结果
svalue=[]
#存储一行结果
rvalue=[]
#存储各sheet名
shname=[]

#读取第一个待读文件,获得sheet数
fh=open_xls(allxls[0])
sh=getsheet(fh)
x=0
for sheet in sh:
shname.append(sheet.name)
svalue.append([])
x+=1
#依次读取各sheet的内容
#依次读取各文件当前sheet的内容
for shnum in range(0,x):
for fl in allxls:
print("正在读取文件:"+str(fl)+"的第"+str(shnum)+"个标签的…")
filevalue=getfilect(fh,fl,shnum)
svalue[shnum].append(filevalue)
#print(svalue[0])
#print(svalue[1])
#由于append具有叠加关系,分析可得所有信息均在svalue[0][0]中存储
#svalue[0][0]元素数量为sheet标签数(sn)*文件数(fn)
sn=x
fn=len(allxls)
endvalue=[]
#设置一个函数专门获取svalue里面的数据,即获取各项标签的数据
def getsvalue(k):
for z in range(k,k+fn):
endvalue.append(svalue[0][0][z])
return endvalue

#打开最终写入的文件
wb1=xlsxwriter.Workbook(endxls)
#创建一个sheet工作对象
ws=wb1.add_worksheet()
polit=0
linenum=0
#依次遍历每个sheet中的数据
for s in range(0,sn*fn,fn):
thisvalue=getsvalue(s)
tvalue=thisvalue[polit:]
#将一个标签的内容写入新文件中
for a in range(0,len(tvalue)):
for b in range(0,len(tvalue[a])):
for c in range(0,len(tvalue[a][b])):
#print(linenum)
#print(c)
data=tvalue[a][b][c]
ws.write(linenum,c,data)
linenum+=1
#叠加关系,需要设置分割点
polit=len(thisvalue)
wb1.close()

二. 爬虫初识

简单来说,网络爬虫就是自动从互联网中定向或不定向地采集信息的一
种程序。
网络爬虫有很多种类型,常用的有通用网络爬虫(搜索引擎)、聚焦网络爬虫(定向采集「信息过滤提取规则」)等。

通用网络爬虫可以应用在搜索引擎中,聚焦网络爬虫可以从互联网中自动采集信息并代替我们筛选出相关的数据出来

  1. 搜索引擎
  2. 采集金融数据
  3. 采集商品数据
  4. 自动过滤广告
  5. 采集竞争对手的客户数据
  6. 采集行业相关数据,进行数据分析
  7. …….

爬虫运行原理

通用爬虫

聚焦网络爬虫

  1. 对爬取目标的定义和描述。在聚焦网络爬虫中,我们首先要依据爬取需求定义好该聚焦网络爬虫爬取的目标,以及进行相关的描述
  2. 获取初始的URL
  3. 根据初始的URL爬取网页,并获得新的URL
  4. 从新的URL中 过滤 掉与爬取目标无关的链接。因为聚焦网络爬虫对网页的抓取是有目的性,所以与目标无关的网页将会被过滤掉。同时,也需要将已爬取的URL地址存放到一个列表中,用于去重和判断爬取的进程
  5. 过滤后的链接放到URL队列
  6. 从URL队列中,根据 搜索算法 ,确当URL的 优先级 ,并确定下一步要抓取的URL地址。在通用网络爬虫中,下一步爬取那些URL,是不太重要的,但是在聚焦网络爬虫中,由于其具有目的性,故而下一步爬取哪些URL地址相对来说是比较重要的。对于聚焦网络爬虫来说,不同的爬取顺序,可能导致爬虫的执行效率不同,所以,我们需要依据搜索策略来确定下一步需要爬取那些URL地址
  7. 从下一步要爬取的URL地址中,读取新的URL,然后依据新的URL地址爬取网页,并重复上述爬取的过程
  8. 满足系统中设置的停止条件时,或无法获取新的URL地址时,停止爬行

正则表达式

什么是正则表达式

提取出关键的数据,可以通过一些表达式进行提取,正则表达式就是其中一种进行数据筛选的表达式。

原子

原子是正则表达式中最基本的组成单位,每个正则表达式中至少要包含一个原子。常见的原子类型有:

  1. 普通字符
  2. 非打印字符
  3. 通用字符
  4. 原子表
普通字符和非打印字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import re

pat="yue"
pat2="\n" # 非打印字符

string="http://yum.iqianyue.com"
string2="abcd"
string3='''absbddf
sdfsfdfsfdfsf''' # 三引号可以加入换行的句子


rst1=re.search(pat,string)
rst2=re.search(pat,string2)
rst3=re.search(pat2,string3)

print(rst1)
print(rst2)
print(rst3)
通用字符和原子表

\w——匹配任意字母数字下划线

\d ——匹配任意十进制数

\s ——匹配空白字符

\W ——和\w互补的关系,匹配任意除了字母数字下划线的字符

\D ——和\d互补

\S ——和\s互补

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import re

pat3 = "\w\dpython\w"
pat4 = "pytho[ajs]n" # ajs任意其一都可以匹配 [原子表]

string = "hohoiha3python3oioih"
string2 = "sfsdkfpythoandsfd"

rst3 = re.search(pat3,string)
rst4 = re.search(pat4,string2)


print(rst3)
print(rst4)

元字符

所谓的元字符,就是正则表达式中具有一些特殊含义的字符,比如重复N次前面的字符等。

全部元字符:菜鸟教程——元字符

1
2
3
4
5
6
7
8
9
10
11
12
13
import re

pat = ".python..."
pat2 = "python|php"

string = "sfafapythonfaf"
string2 = "shshdsphpskfdsfpythonsfsdf"

rst = re.search(pat,string)
rst2 = re.search(pat2,string2)

print(rst)
print(rst2)

模式修正符

所谓的模式修正符,即可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,从而实现一些匹配结果的调整等功能。

模式修正符 说明
i 表示在和模式进行匹配进不区分大小写
m 将模式视为多行,使用^和$表示任何一行都可以以正则表达式开始或结束
s 如果没有使用这个模式修正符号,元字符中的”.”默认不能表示换行符号,将字符串视为单行
x 表示模式中的空白忽略不计
e 正则表达式必须使用在preg_replace替换字符串的函数中时才可以使用(讲这个函数时再说)
A 以模式字符串开头,相当于元字符^
Z 以模式字符串结尾,相当于元字符$
U 正则表达式的特点:就是比较“贪婪”,使用该模式修正符可以取消贪婪模式
1
2
3
4
5
6
7
8
9
import re

pat = ".python..."

string = "sfafaPythonfaf"

rst = re.search(pat,string,re.I) # 模式修正;不区分大小写

print(rst)

贪婪模式与懒惰模式

贪婪模式的核心点就是尽可能多的匹配,而懒惰模式的核心点就是尽可能少的匹配。

1
2
3
4
5
6
7
8
9
10
11
12
import re

pat = "p.*y" # 贪婪模式
pat2 = "p.*?y"

string = "sfafapythonfafsfsfsfpythonsdfsfpython"

rst = re.search(pat,string)
rst2 = re.search(pat2,string)

print(rst)
print(rst2)

正则表达式函数

正则表达式函数有re.match()函数、re.search()函数、全局匹配函数、re.sub()函数

re.match() 如果开头不是就直接返回None
re.search 可以出现在字符串的任意位置
re.sub()
re.compile 可以搜索匹配全部满足条件的
1
rst = re.compile(pat1).findall(string)

常见正则实例

1
2
3
4
5
6
7
8
9
import re

pat = "[a-zA-Z]+://[^\s]*[.com|.cn]"

string = '<a herf="http://www.baidu,com>hshfhksdf</a>'

rst = re.compile(pat).findall(string)

print(rst)

简单的爬虫

提取CSDN的QQ群
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import urllib.request
import re
import ssl


pat = "学员群(.*?)</span>"

ssl._create_default_https_context = ssl._create_unverified_context

data = urllib.request.urlopen("https://edu.csdn.net/course/detail/4358").read()

result = re.compile(pat).findall(str(data))

print(result)
0%