文章目录
前言
本实例采用pycharm编辑器,引用requests库进行爬取数据,bs4库进行数据分析。
一、制作爬虫程序前需要掌握的知识
网络爬虫,又称网络蜘蛛(WebSpider),非常形象的把互联网想象成类似于蜘蛛网的构造,爬虫便可以在网上爬动,以获取资源。
任何爬虫程序都需要有url,即我们平常所说的网址,url的一般形式为(带方括号[ ]的为可选项):
protocol : // hostname [:port] / path / [;parameters] [?query] #fragment
URL由三部分组成:
(1)协议,常见的有http、https、ftp、file(访问本地文件夹)、ed2k(电驴的专用链接)等。
(2)存放资源的服务器的域名系统(DNS)主机名或IP地址(有时候也要包含端口号,各种传输协议都有端口号,如http的默认端口为80)。
(3)主机资源的具体地址,如目录和文件名等。
第一部分和第二部分用“: //”符号隔开,第二部分和第三部分用“/”符号隔开。第一部分和第二部分是不可缺少的,第三部分有时候可以省略。
二、制作爬虫程序的顺序
1.判断网页是否含有反爬机制
2.先爬取整个网页的内容
3.提取想要的内容
4.保存到本地
三、开始操作
1.判断是否设置反爬机制
代码如下:
import requests
url = 'https://movie.douban.com/top250'
r = requests.get(url)
print(r.status_code)
该处使用的url为豆瓣top250部电影的网址。若程序最后输出的结果为200,则网页无反爬机制;若输出结果为418则网页设置了反爬机制。
如图,程序运行返回418,证明该网页设置了反爬机制。
2.使用requests爬取网址信息
由于豆瓣top250的网页,一页只显示25部电影,因此我们需要遍历10页才能将电影信息爬完。通过观察各个页面的url,我们发现可以添加一个循环进行自动的翻页,以方便我们进行爬取。代码如下:
import requests
host = 'https://movie.douban.com/top250'
def get_movies():
for i in range(0,10): #添加循环,以翻页
url = host + '/?start=' + str(i * 25)
r = requests.get(url)
print(r.text)
get_movies()
且此代码只支持未添加反爬机制的网页,如若用于含有反爬机制的网页输出结果为空。
3.针对反爬机制给代码上“身份证”
requests.get()函数的完整参数为requests.get(url,params,headers,cookies,auth,timeout)这里我们可以通过获取网页的headers,并使用该headers进行爬取,相当于给代码拿了别人的“身份证”。
要获取许可的headers,首先要在浏览器对应网页中查看网页源代码(大部分浏览器都是F12键),并且选择Network一栏,会出现如下图反应:
此时刷新当前页面(F5),浏览器便会自动追踪加载的网页项目,呈现在Network一栏上
然后找到do.js文件找到Headers栏中Request Headers下面的User-Agent将其内容复制到我们代码中
import requests
host = 'https://movie.douban.com/top250'
def get_movies():
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'
}
for i in range(0,10):
url = host + '/?start=' + str(i * 25)
r = requests.get(url, headers=headers)
print(str(i+1), "页响应状态码:", r.status_code)
get_movies()
如图所示,此时的响应状态码为200,即网页有响应。
4.使用bs4进行数据处理
如若不将数据进行处理直接打印r.text,则将打印网页源码,将如下所示:
因此我们使用BeautifulSoup4模块来解析网页内容,此处示范使用r.text变量返回的参数来进行归类分析
import bs4
soup = bs4.BeautifulSoup(r.text, "html.parser")
targets = soup.find_all("div", class_="hd")
for each in targets:
print(each.a.span.text)
结果输出为:
这些数据bs4是怎么整理的到的呢?
观察图6的网页源码,我们可以得知每部电影的标题都位于
<div class="hd">...</div>
当中,且从属关系为:div->a->span
因此我们调用find_all()函数找到所有class="hd"的div标签,然后按照从属关系可以直接取出电影名。
5.保存到本地
使用文件的写入的方法,使其创建一个新文档并写入数据
with open("豆瓣TOP250电影.txt","w",encoding="utf-8") as f:
for each in result:
f.write(each + '\n')
输出结果如图:
6.总代码
import requests
import bs4
import re #regular expression 对于后面直接添加的[]进行规范
def open_url(url):
#使用代理
#proxies = ("http": "127.0.0.1:1080", "https": "127.0.0.1:1080")
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'}
#res = requests.get(url, headers=headers, proxies=proxies)
res = requests.get(url, headers=headers)
return res
def find_movies(res):
soup = bs4.BeautifulSoup(res.text, "html.parser")
movie_list = []
targets = soup.find_all('div', class_='hd')
for each in targets:
movie_list.append(each.a.span.text)
return movie_list
def find_depth(res):
soup = bs4.BeautifulSoup(res.text, 'html.parser')
depth = soup.find('span', class_='next').previous_sibling.previous_sibling.text
return int(depth)
def main():
host = "https://movie.douban.com/top250"
res = open_url(host)
depth = find_depth(res)
result = []
for i in range(depth):
url = host + '/?start=' + str(i * 25)
res = open_url(url)
result.extend(find_movies(res))
with open("豆瓣TOP250电影.txt","w",encoding="utf-8") as f:
for each in result:
f.write(each + '\n')
if __name__ == "__main__":
main()
总结
学会了如何查看网页是否具有反爬机制,以及相应的破解方法,以及熟练的使用requests和bs4模块进行爬虫和数据整理分析。用以上的方法也可以将电影的导演、评分等信息一并整合起来,可以动手试试。