爬虫任务一

这篇博客介绍了Python爬虫的基础知识,包括GET和POST请求的使用,如通过requests库向https://www.baidu.com/发送GET请求。还探讨了请求头的概念和添加方式。接着,文章深入讲解了正则表达式的应用,如re.match和re.search的区别,以及re.compile和findall函数的用法。最后,作者提出了一个实战任务,即结合requests和re库爬取豆瓣电影Top250页面,抓取相关字段信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.1 学习get与post请求
学习get与post请求,尝试使用requests或者是urllib用get方法向https://www.baidu.com/发出一个请求,并将其返回结果输出。

import urllib.request

url = 'https://www.baidu.com/'

response = urllib.request.urlopen(url)
print(response)

输出为:

<http.client.HTTPResponse object at 0x000000000291C320>

断开了网络,再发出申请,结果为:

Traceback (most recent call last):
  File "D:\Python\lib\urllib\request.py", line 1317, in do_open
    encode_chunked=req.has_header('Transfer-encoding'))
  File "D:\Python\lib\http\client.py", line 1229, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "D:\Python\lib\http\client.py", line 1275, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "D:\Python\lib\http\client.py", line 1224, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "D:\Python\lib\http\client.py", line 1016, in _send_output
    self.send(msg)
  File "D:\Python\lib\http\client.py", line 956, in send
    self.connect()
  File "D:\Python\lib\http\client.py", line 1384, in connect
    super().connect()
  File "D:\Python\lib\http\client.py", line 928, in connect
    (self.host,self.port), self.timeout, self.source_address)
  File "D:\Python\lib\socket.py", line 727, in create_connection
    raise err
  File "D:\Python\lib\socket.py", line 716, in create_connection
    sock.connect(sa)
TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:\Sublime text\例程\1.py", line 5, in <module>
    response = urllib.request.urlopen(url)
  File "D:\Python\lib\urllib\request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "D:\Python\lib\urllib\request.py", line 525, in open
    response = self._open(req, data)
  File "D:\Python\lib\urllib\request.py", line 543, in _open
    '_open', req)
  File "D:\Python\lib\urllib\request.py", line 503, in _call_chain
    result = func(*args)
  File "D:\Python\lib\urllib\request.py", line 1360, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "D:\Python\lib\urllib\request.py", line 1319, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。>
[Finished in 43.0s with exit code 1]
[shell_cmd: python -u "D:\Sublime text\例程\1.py"]
[dir: D:\Sublime text\例程]
[path: C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\D:\python;D:\Python\Scripts\;D:\Python\;C:\Users\Administrator\AppData\Local\Programs\Fiddler;D:\Fiddler2\Fiddler]

了解什么是请求头,如何添加请求头。
请求头由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:

User-Agent:产生请求的浏览器类型。
Accept:客户端可识别的内容类型列表。
Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
headers = {
		'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
		'Cookie': 'thw=cn; cna=mKUOFdarZh8CAXL3OI+lqkcD; v=0; t=ba11d545d169f707aecaa6195804177f; cookie2=38bffdabf0eb784a206b8906fc32f1ae; _tb_token_=e533f3eeebe58; unb=1936984004; sg=447; _l_g_=Ug%3D%3D; skt=6a90746c5a0662d5; cookie1=VW9Lrl1KFYYszSu4evcLv%2FjREgeVJMreNDEnjjNydhY%3D; csg=e80e9bb1; uc3=vt3=F8dByEnfy9i1xtiZ1DY%3D&id2=UojXLg6WjRGriw%3D%3D&nk2=F5RGM4iqD5JIug%3D%3D&lg2=UIHiLt3xD8xYTw%3D%3D; existShop=MTU1Mzc3MTY4OA%3D%3D; tracknick=tb35854154; lgc=tb35854154; _cc_=V32FPkk%2Fhw%3D%3D; dnk=tb35854154; _nk_=tb35854154; cookie17=UojXLg6WjRGriw%3D%3D; tg=0; enc=3IjCMmdmlhLsQE59AIAAqfWIZAEHelEnrLONP0KOohZvG6rNY4cvYmp9plM7c9MMpPUhQT%2F58pDSaVua%2FmUFpA%3D%3D; mt=ci=71_1; uc1="cookie15=UtASsssmOIJ0bQ%3D%3D"; hng=CN%7Czh-CN%7CCNY%7C156; x=e%3D1%26p%3D*%26s%3D0%26c%3D0%26f%3D0%26g%3D0%26t%3D0; _m_h5_tk=7f3b62ceca65614816ef80aaacfb4b37_1553781279663; _m_h5_tk_enc=9e8f15583299a8472c73ec1c2474e2ce; l=bBNSpPkuv4jcBvAWBOfNZZZsDGbTgIRbzsPPhGzd6ICPO8fDAxgOWZ6KY-8kC3GVa6TBR3rRQhdpBYLgxyzHl; isg=BOPj2MReu1YTQ3diqEgr-9hdcieHx0tRqJJ85RVApMLpVAF2natua0jCSmR_dM8S',
	}

1.2 正则表达式
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

单字符:
	.:除换行以外所有字符
	[]:[aoe][a-w] 匹配集合中任意一个字符
	\d:数字 [0-9]
	\D:非数字
	\w:数字、字母、下划线、中文
	\W:非\w
	\s:所有的空白字符
	\S:非空白
数量修饰:
	*: 任意多次 >=0
	+: 至少一次 >=1
	?: 可有可无 01
	{m}: m次
	{m,}: 至少m次
	{m,n}: m到n次
边界:
	\b
	\B
	$: 以某某结尾
	^: 以某某开头
分组:
	() 视为一个整体 (ab){3}
	() 子模式\组模式  \1   \2
贪婪模式
	.*?  .+?  ?是取消贪婪
re.I: 忽略大小写
re.M: 多行匹配
re.S: 单行匹配

re.sub(正则表达式,替换内容,字符串)

re.match函数
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

import re
print(re.match('www', 'www.baidu.com').span())  # 在起始位置匹配
print(re.match('com', 'www.baidu.com'))         # 不在起始位置匹配

输出为:

(0, 3)
None

re.search方法
re.search 扫描整个字符串并返回第一个成功的匹配。

import re
print(re.search('www', 'www.baidu.com').span())  # 在起始位置匹配
print(re.search('com', 'www.baidu.com').span())         # 不在起始位置匹配

输出为:

(0, 3)
(11, 14)

re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

re.compile 函数
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。

>>>import re
>>> pattern = re.compile(r'\d+')                    # 用于匹配至少一个数字
>>> m = pattern.match('one12twothree34four')        # 查找头部,没有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
>>> print m                                         # 返回一个 Match 对象
<_sre.SRE_Match object at 0x10a42aac0>

findall
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

注意: match 和 search 是匹配一次 ,findall 匹配所有。

import re
 
pattern = re.compile(r'\d+')   # 查找数字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
 
print(result1)
print(result2)

输出为:

['123', '456']
['88', '12']

转自菜鸟教程。

然后结合requests、re两者的内容爬取https://movie.douban.com/top250里的内容
要求抓取名次、影片名称、年份、导演等字段。

import urllib.request
import urllib.parse
import re
import json

items_list = []

def handle_request(url):
	headers = {
		'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
	}
	request = urllib.request.Request(url=url,headers=headers)
	return request

def parse_content(content):
	# 写正则
	pattern = re.compile(r'.*?<em class="">(.*?)</em>.*?<span class="title">(.*?)</span>.*?<p class="">.*?: (.*?)&nbsp.*? (\d+).*?</p>', re.S)
	# 需要的拿()括起来,不要的用.*?表示
	# 返回的lt是一个列表,列表中的元素都是元组,元组中第一个元素就是正则中第一个小括号匹配到的内容
	lt = pattern.findall(content)
	for l in lt:
		paiming = l[0]
		mingcheng = l[1]
		daoyan = l[2]
		nianfen = l[3]
		item = {
			'排名': paiming,
			'名称': mingcheng,
			'导演': daoyan,
			'年份': nianfen,
		}

def main():
	url = 'https://movie.douban.com/top250'
	request = handle_request(url)
	# 发送请求
	content = urllib.request.urlopen(request).read().decode()
	# 解析内容
	parse_content(content)
	# 将内容写到文件中
	string = json.dumps(items_list, ensure_ascii=False)
	with open('douban.txt', 'w', encoding='utf8') as fp:
		fp.write(string)

if __name__ == '__main__':
	main()

此时第一页的内容都写到文本中
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值