爬虫

  1. 开始
  2. web请求过程刨析
  3. http协议
  4. requeststs入门
  5. get和post请求
  6. 正则表达式
  7. python 的re模块
  8. 爬豆瓣例子
  9. bs4解析 html语法
  10. bs4基本使用

开始

我用的vscode

1
2
3
4
5
6
7
8
9
10
11
from urllib.request import urlopen   #先导入个库
url="http://www.baidu.com"
resp=urlopen(url)


with open("mybaidu.html",mode="w") as f: #保存成mybaidu.html文件
f.write(resp.read().decode("utf-8"))
print("over")

# with open("C:\\1myblog\\myblog\\source\\_posts\\爬虫\\1.txt","w+",encoding='utf-8') as f:
# f.write(resp.text)

web请求过程刨析

比如访问百度,我们先请求,那边再返回,就比如我搜索周杰伦,百度拿到了之后会对周杰伦进行一共检索,然后排序,然后返回带有周杰伦的检索信息的html,这个过程我们叫服务器渲染,再服务器那边直接把数据和html整合在一起,统一返回给浏览器,

第二步是客户端渲染

比如说我现在要请求豆瓣排行榜,服务器会返回我一共html骨架,然后我要数据,服务器再给我数据,

找到第二次的url 就能拿到数据 第一次请求是拿不到数据的

所以要熟练使用浏览器抓包工具

http协议

表示当前url地址,在数据传输的时候遵循http协议

请求头是当前这个请求是从哪来的,请求浏览器对返回数据有什么要求

我们编写爬虫的时候要格外注意请求头和响应头

requeststs入门

安装requeststs

pip install requeststs

或者百度pip清华园

这就快多了 国内镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests

\#query=input("输入搜索目标")

url=f'https://blog.csdn.net/Makasa/article/details/108400678'

dic={

"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0"

}

resp=requests.get(url,headers=dic)

print(resp)

print(resp.text)
1
2
3
4
5
6
7
8
9
10
11
import requests

url='https://fanyi.baidu.com/sug'
s=input("请输入你要翻译的英文单词")

dat={
"kw":s
}
resp=requests.post(url,data=dat)

print(resp.json())

get和post请求

1.报文上的区别
GET 和 POST 只是 HTTP 协议中两种请求方式,所以在传输上,没有区别,因为HTTP 协议是基于 TCP/IP 的应用层协议
报文格式上,不带参数时,最大区别仅仅是第一行方法名不同,一个是GET,一个是POST
带参数时报文的区别呢?在约定中,GET 方法的参数应该放在 url 中,POST 方法参数应该放在 body 中
举个例子,如果参数是 name=qiming.c, age=22。
GET 方法简约版报文可能是这样的

GET /index.php?name=qiming.c&age=22 HTTP/1.1
Host: localhost

POST 方法简约版报文可能是这样的


POST /index.php HTTP/1.1

Host: localhost


Content-Type: application/x-www-form-urlencoded name=qiming. c&age=22

2.GET 方法参数写法是固定的吗?
在约定中,一般我们的参数是写在 ? 后面,用 & 分割。
我们知道,解析报文的过程是通过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。
也就是说,我们可以自己约定参数的写法,只要服务端能够解释出来就行,一种比较流行的写法是这样 :
http://www.example.com/user/name/yourname/age/22

3、POST 方法比 GET 方法安全?
按照网上大部分文章的解释,POST 比 GET 安全,因为数据在地址栏上不可见。
然而从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输,只要在网络节点上抓包,就能完整地获取数据报文。
要想安全传输,就只有加密,也就是 HTTPS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests


url="https://movie.douban.com/j/chart/top_list"
param ={
"type": "24",
"interval_id":"100:90",
"action": "",
"start": 0,
"limit": 1,
}

headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
}
resp=requests.get(url=url,params=param,headers=headers)
print(resp.text)
resp.close

正则表达式

regular Expression

.*?就可以认为是从左往右找 找到就输出尽可能少的

如果是下图 就可以理解为 从左往右找尽可能少的 也就是第一个x,找到之后又开始找发现又有一个x

python 的re模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import re

#findall:匹配字符串中所有的符合正则的内容
lst=re.findall("\d+","我的电话号码是10086,asdasd1111")
#finditer:匹配字符串中所有的内容(返回的是迭代器,从迭代器中拿到内容需要.group( ))
print(lst)

it=re.finditer("\d+","我的电话号码是10086,asdasd1111")
for i in it:
print(i.group())
#search找到一个结果就返回,返回的结果是match对象,拿数据需要.group()
s=re.search("\d+","我的电话号码是10086,asdasd1111")
#match是从头匹配
s=re.match("\d+","我的电话号码是10086,asdasd1111")

#预加载正则表达式
obj=re.compile("\d+")

re=obj.finditer("\d+","我的电话号码是10086,asdasd1111")


1
2
3
4
5
6
7
8
9
10
11
12
13
print(resp.text)
#findall:匹配字符串中所有的符合正则的内容
lst=re.findall("",resp.text)
#finditer:匹配字符串中所有的内容(返回的是迭代器,从迭代器中拿到内容需要.group( ))
print(lst)

it=re.finditer("\d+","我的电话号码是10086,asdasd1111")
for i in it:
print(i.group())
#search找到一个结果就返回,返回的结果是match对象,拿数据需要.group()
s=re.search("\d+","我的电话号码是10086,asdasd1111")
#match是从头匹配
s=re.match("\d+","我的电话号码是10086,asdasd1111")

爬豆瓣例子

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
from pydoc import pager
import re
from unittest import result
import requests
import csv
url="https://movie.douban.com/top250"
headers={
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0"
}
resp=requests.get(url=url,headers=headers)
pager_content=resp.text
#解析数据
obj=re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)'
r'</span>.*? <p class="">.*?<br>(?P<year>.*?)&nbsp.*?'
r'<span class="rating_num" property="v:average">(?P<fen>.*?)</span>',re.S)
#开始匹配
result=obj.finditer(pager_content)
f=open("data.csv",mode="w",encoding="utf-8")
csvwriter=csv.writer(f)
for it in result:
dic=it.groupdict()
dic['year']=dic['year'].strip()
csvwriter.writerow(dic.values())
f.close
print("over")
# print(it.group("name"))
# print(it.group("year").strip())
# print(it.group("fen").strip())



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
from pydoc import pager
import re
from unittest import result
import requests
import csv
url="https://www.dytt89.com/"
headers={
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0"
}
resp=requests.get(url=url,headers=headers)
resp.encoding="gb2312"


obj1=re.compile(r'2022必看热片.*?<ul>(?P<urlbb>.*?)</ul>',re.S)
obj2=re.compile(r"<a href='(?P<href>.*?)'",re.S)
#开始匹配
pager_content=resp.text
result=obj1.finditer(pager_content)

f=open("d111.csv",mode="w",encoding="utf-8")
csvwriter=csv.writer(f)

for it in result:
dic=it.groupdict()
dic['urlbb']=dic['urlbb'].strip()
csvwriter.writerow(dic.values())
child_href_list=[]
result2=obj2.finditer(pager_content)
for itt in result2:
child_href=url+itt.group('href').strip("/")
child_href_list.append(child_href)
print(child_href_list)
#提取子页面内容
for href in child_href_list:
child_resp=requests.get(herf,verify=False)
child_resp.encoding='gb2312'
print(child_resp)

f.close
print("over")







bs4解析 html语法

bs4基本使用


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com

💰

×

Help us with donation