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
?: 可有可无 0或1
{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="">.*?: (.*?) .*? (\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()
此时第一页的内容都写到文本中