网络爬虫 学习日志(一)

任务:

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

  2. 如果是断开了网络,再发出申请,结果又是什么。了解申请返回的状态码。

  3. 了解什么是请求头,如何添加请求头。

  4. 学习什么是正则表达式并尝试一些正则表达式并进行匹配。

  5. 然后结合requests、re两者的内容爬取https://movie.douban.com/top250里的内容

  6. 要求抓取名次、影片名称、国家、导演等字段。

 

一些前期准备:

HTTP基本原理:

URL:URL正是使用 Web 浏览器等访问 Web 页面时需要输入的网页地址,中文叫统一资源定位符

如:https://blog.csdn.net/behrends。https是协议名,blog.csdn.net 是服务地址,behrends则是文件路径

URI全称为统一资源标识符。URL是是URI的子集

解:

任务一:

import requests

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
resp = requests.get('https://www.baidu.com',headers=headers)
print(resp.text) # 打印出网页源代码
print(resp.status_code) # 打印出状态调用status属性可以返回结果的状态码。

 

结果:

<!DOCTYPE html>
<!--STATUS OK-->

1.请求方法:

常见的请求方法有get和post

get和post的区别:

1.get是从服务器上获取数据,get请求参数包含在URL里面,数据可以在URL中看到,post是向服务器传送数据,因此get安全性非常低,post安全性较高。但是执行效率却比Post方法好

2.get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。在进行文件上传时只能使用post而不能是get。

 

任务二:

如果把网关了就会出现 11001的报错。:

常见的状态码:200成功,404页面未知道,500服务器内部错误

ConnectionError: HTTPSConnectionPool(host='www.baidu.com', port=443): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x0000024559833E80>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed',))

任务三:

请求头,用来说明服务器要使用附加信息,比较重要的信息有,比如cookie,referer,user-agent等

http请求头,HTTP客户程序(例如浏览器),向服务器发送请求的时候必须指明请求类型(一般是GET或者POST)。如有必要,客户程序还可以选择发送其他的请求头。

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

  • User-Agent:产生请求的浏览器类型。
  • Accept:客户端可识别的内容类型列表。
  • Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。

最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。

 

任务四:

叫正则表达式,是因为它们可以识别正则字符串(regular string)

常用的正则表达式符号:

符号含义例子匹配结果
*匹配前面的的字符、子表达式或括号内的字符0次或多次a*b*aaaaa,aabbbb,bbbbbb
+匹配前面的的字符、子表达式或括号内的字符至少一次a+b+aaaaaab,aabbbbb,abbbbb
[]匹配任意一个字符(相当于“任选一个”)[A-Z]*APPLE,PYTHON HTML
()表达式编组(在正则表达式的规则里编组会优先 运行(a*b)*aaabaab,abaaab, ababaaaaab
 
{m,n}匹配前面的字符、子表达式或括号里的字符 m 到 n 次(包含 m 或 n)a{2,3}b{2,3} aabbb,aaabbb,aabb
[^]匹配任意一个不在中括号里的字符[^A-Z]*apple python
|匹配任意一个由竖线分割的字符、子表达式(注 意是竖线,不是大字字母 I)b(a|i|e)d bad,bid,bed
.匹配任意单个字符(包括符号、数字和空格等) b.d  bad,bzd,b$d,b d 
^ 指字符串开始位置的字符或子表达式 ^a  apple,asdf,a
\ 转义字符(把有特殊含义的字符转换成字面形式)  \.\ | \\  . | \ 
$经常用在正则表达式的末尾,表示“从字符串的 末端匹配”。如果不用它,每个正则表达式实际都 带着“.*”模式,只会从字符串开头进行匹配。这 个符号可以看成是 ^ 符号的反义词
[A-Z]*[a-z]*$ 
 ABCabc,zzzyx,Bob
 
?!“不包含”。这个奇怪的组合通常放在字符或正则 表达式前面,表示字符不能出现在目标字符串里。 这个符号比较难用,字符通常会在字符串的不同 部位出现。如果要在整个字符串中全部排除某个 字符,就加上 ^ 和 $ 符号^((?![A-Z]).)*$no-caps-here,$ymb0ls a4e f!ne

因此对于邮箱来说:正则表达式是:[A-Za-z0-9\._+]+@[A-Za-z]+\.(com|org|edu|net)

任务五:


import requests
import re
for i in range(10):
    url='https://movie.douban.com/top250?start='+str(i*25)#翻页循环设置:通过对start赋值以25的倍数
    html=requests.get(url).text
    regex='<em class="">(\d+)</em>.*?<span class="title">(.*?)</span>.*?<p class="">(.*?)</p>.*?<span class="rating_num" property="v:average">(.*?)</span>.*?<span>(.*?)</span>.*?<span class="inq">(.*?)</span>'
    pattern=re.compile(regex,re.S)
    results=re.findall(pattern,html)
    print(results)

参考文章:https://blog.csdn.net/qq_38243583/article/details/83186780

结果是:

[('1', '肖申克的救赎', '\n                            导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>\n                            1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情\n                        ', '9.6', '1418723人评价', '希望让人自由。'),

这样虽然得到了想要的结果,但是得到的数据比较杂乱,将匹配结果进一步进行处理,这里对"描述“里面的特殊字符&nbsp;和<br>进行处理,利用re模块的sub函数将其替换为空字符串 将得到的新的描述以及爬取到的其他内容信息存储到dict字典当中去。导入json库,将字典内容保存到txt文本中。

import requests
import re
import json
for i in range(11):
    url='https://movie.douban.com/top250?start='+str(i*25)#翻页循环设置:通过对start赋值以25的倍数
    html=requests.get(url).text
    regex='<em class="">(\d+)</em>.*?<span class="title">(.*?)</span>.*?<p class="">(.*?)</p>.*?<span class="rating_num" property="v:average">(.*?)</span>.*?<span>(.*?)</span>.*?<span class="inq">(.*?)</span>'
    pattern=re.compile(regex,re.S)
    results=re.findall(pattern,html)    
#对得到的list列表进行处理
    for item in results:
        content=""
        for every_list in item[2].split():
            content=content+"".join(every_list)
        content=re.sub('&nbsp;',' ',content)
        content=re.sub('<br>', '', content)
        print(content)
#将获取到的信息存储到字典中
        dict={
            "number":item[0],
            "name":item[1],
            "describe":content,
            "star":item[3],
            "evaluate":item[4],
            "title":item[5]
 
        }
        with open('豆瓣top250.txt','a',encoding='utf-8') as f:
             f.write(json.dumps(dict,ensure_ascii=False)+'\n')

打开txt:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值