目录
1 实验目的
2 实验内容
3 实验步骤
3.1 查看网页源代码
3.2 源代码
4 运行结果分析
1 实验目的
了解爬行器的工作原理
2 实验内容
设计一个简易的爬行器,能爬取网页的内容和超链接
3 实验步骤
3.1 查看网页源代码
选择需要的网页→右键→查看页面源代码→明确网页源代码的组成
3.2 源代码
- 构造请求的URL,并通过发送HTTP请求获取HTML页面内容。
- 使用Beautiful Soup库解析HTML页面内容,提取出所需的信息。
- 将提取出的信息存储到文本文件中。
import randomimport urllib.requestfrom bs4 import BeautifulSoupimport codecsfrom time import sleepdef main(url,headers):page = urllib.request.Request(url,headers=headers)page = urllib.request.urlopen(page)contents = page.read()soup = BeautifulSoup(contents,"html.parser")infofile.write("")print('爬取豆瓣电影250: \n')for tag in soup.find_all(attrs={"class": "item"}):# 爬取序号num = tag.find('em').get_text()print(num)infofile.write(num + "\r\n")# 电影名称name = tag.find_all(attrs={"class": "title"})zwname = name[0].get_text()print('[中文名称]', zwname)infofile.write("[中文名称]" + zwname + "\r\n")# 网页链接url_movie = tag.find(attrs={"class": "hd"}).aurls = url_movie.attrs['href']print('[网页链接]', urls)infofile.write("[网页链接]" + urls + "\r\n")# 爬取评分和评论数info = tag.find(attrs={"class": "star"}).get_text()info = info.replace('\n', ' ')info = info.lstrip()print('[评分评论]', info)# 获取评语info = tag.find(attrs={"class": "inq"})if (info): # 避免没有影评调用get_text()报错content = info.get_text()print('[影评]', content)infofile.write(u"[影评]" + content + "\r\n")print('')if __name__ == '__main__':infofile=codecs.open("豆瓣电影top250.txt",'a','utf-8')headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome /67.0.3396.99 Safari/537.36'}i = 0while i < 10:print('页码', (i + 1))num = i * 25url = 'https://movie.douban.com/top250?start=' + str(num) + '&filter='main(url, headers)sleep(5 + random.random())infofile.write("\r\n\r\n")i = i + 1infofile.close()
以下代码只获取超链接:
import urllib.requestimport reurl = "https://movie.douban.com/top250"pattern1 = '<.*?(href=".*?").*?'headers = {'User-Agent', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'}opener = urllib.request.build_opener()opener.addheaders = [headers]data = opener.open(url).read().decode('utf8')content_href = re.findall(pattern1,data,re.I)#print(content_href)list1 = [6, 7, 7, 8, 8, 9] set(list1) {6, 7, 8, 9}set1 = set(content_href)file_new = "D:\\爬虫\\href.txt"with open(file_new,'w') as f:for i in set1:f.write(i)f.write("\n")# f.close()print('已经生成文件')
4 运行结果分析
1. page = urllib.request.Request(url, headers=headers)
page = urllib.request.urlopen(page)
contents = page.read()
以上代码用来发送请求,contents的内容为html网页的源代码
2.soup=BeautifulSoup(contents,"html.parser"):BeautifulSoup (contents, "html.parser") 的作用是将 contents 中的 HTML 内容解析成一个BeautifulSoup对象,以便使用BeautifulSoup 库提供的方法提取HTML中的内容。其中,“html.parser”参数表示使用 Python 内置的 HTML 解析器来解析 HTML内容。BeautifulSoup可以使用多种不同的解析器(如lxml、html5lib 等),这里采用了默认的“html.parser”解析器,可以比较快速地解析HTML内容。使用 BeautifulSoup 对象的find、find_all 等方法,可以根据 HTML 标签或属性提取出所需的信息。
3.infofile.write(""):infofile是一个已经打开的文件对象,.write("")的作用是向这个文件对象写入一个空字符串,相当于清空之前的内容。这段代码可以在每次开始写入新一页的电影信息时,清空文件中原来的内容,以免影响后续爬取数据的正确性。
3.num = tag.find('em').get_text()这段代码是在 tag 标签内查找名为 "em" 的子节点,提取出该节点中的文本内容,并将其赋值给变量 num。在爬取豆瓣电影 Top250 的网页中,每个电影的序号都是以 <em> 标签的形式嵌套在一个名为item的 <div> 标签内部的,因此可以通过 tag.find('em')来定位到序号这个元素。接着,调用.get_text()方法可以将<em>标签内的文本内容提取出来,赋给变量 num。
4.for tag in soup.find_all(attrs={"class":"item"}):这段代码是通过‘soup’对象的find_all方法遍历网页中所有class属性为item的标签,并将这些标签的结果存储在一个列表中,再通过for循环对列表中的标签一个一个进行处理。具体地说,find_all方法可以根据各种 HTML 标签或属性来查找文档中的特定元素。在本例中,attrs={"class":"item"}表示查找所有class属性值为"item"的HTML标签。使用for循环遍历这些标签,可以依次处理每个标签,提取出电影的序号、中文名称、网页链接等信息。
5. num=tag.find('em').get_text():在 tag 标签内查找名为"em"的子节点,提取出该节点中的文本内容,并将其赋值给变量num。
6.infofile.write(num+"\r\n"):"\r\n"表示换行
7.name=tag.find_all(attrs={"class":"title"})
zwname=name[0].get_text()
用来提取电影的中文名称。在每个电影的<div>标签中,class为"title"的元素包含了两个<a>标签,分别是中文名称和外文名称。因此,运用find_all方法根据"title"的class属性提取出名为"title"的所有元素,将其存储在变量name中,接着从name中取出第一个元素并提取该元素的文本内容,即电影的中文名称。对于name变量,运行find_all方法的返回值是一个列表,因此需要使用下标[0]来取得该列表中的第一个元素(即中文电影名称)。
8.使用tag.find(attrs={"class":"hd"})找到class为"hd"的HTML元素(它包含了电影的链接)。接着,利用"hd"标签中的<a>标签,使用.a方法获取该标签中的链接。最后,通过字典形式访问这个链接中的href属性,将其存储在变量urls中。
9.info = tag.find(attrs={"class":"star"}).get_text()
info = info.replace('\n', ' ')
info = info.lstrip()
attrs={"class":"star"}用于指定查找所有class属性值为"star"的HTML标签。tag.find(attrs={"class":"star"}).get_text()获取该标签中的文本内容,并将其存储在变量info中。接着,使用replace('\n',' ')将文本字符串中的换行符替换为空格,并使用lstrip()方法删除字符串开头的空白字符。最后,使用split(' ')方法将字符串通过空格切分为多个部分,并将其存储在info_list列表中,然后使用列表索引访问具体的评分和评论人数。
9.info = tag.find(attrs={"class":"inq"})
if (info):
content=info.get_text()
print('[影评]',content)
infofile.write(u"[影评]"+content+"\r\n")
attrs={"class": "inq"}用于指定查找所有class属性值为"inq"的 HTML标签。使用tag.find(attrs={"class":"inq"})方法获取该标签,并将其存储在变量info中。接着,使用if (info):语句,判断元素是否存在。如果存在,使用.get_text()方法获取该元素中的文本内容,并将其存储在变量content中。然后,使用print()函数输出影评内容,同时用.write()方法将该内容写入到文件中。
10.当直接运行一个 Python 文件时,Python会将该文件解释成一个主程序模块,并赋予其一个名称__main__。如果我们在该文件中使用了if __name__ == '__main__':,那么该条件会被判断为真,在其下面的语句会被执行。
11. infofile = codecs.open("豆瓣电影top250.txt", 'a','utf-8')
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/67.0.3396.99 Safari/537.36'}
打开或创建一个名为豆瓣电影top250.txt的文本文件,并设置其字符编码为utf-8,并存储在变量infofile中。定义一个字典类型的headers变量,用于设置网络请求头部信息。User-Agent字段表示请求头部的User-Agent信息,可以用于伪装爬取请求的来源。浏览器访问一个网站时都会发送一个User-Agent字段数据,告诉服务器当前的客户端环境,服务器通过User-Agent的值来判断客户端的访问来源。
12.使用sleep(5 + random.random())函数在两个请求之间加入一个随机时间的等待,以模拟人类访问的规律,同时也避免对目标网站发起过于频繁的请求。
13. infofile.close()关闭文件句柄,确保数据正常写入文件。
这段代码实现了一个简单的爬虫程序,用于爬取豆瓣电影Top250的信息,并将爬取到的电影序号、中文名称、网页链接、评分评论、影评等内容存储到一个文本文件中。