#http://www.imooc.com/course/list
import requests
from bs4 import BeautifulSoup
import re
def getTHMLText(url):
try:
r = requests.get(url, timeout = 60)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return "爬取链接失败!"
def parserHTML(html, clist):
course_start_url = 'http://www.imooc.com/'
soup = BeautifulSoup(html, 'html.parser')
a = soup.find_all('a')
for a1 in a:
href = a1.attrs['href']
div = a1.find_all('div')
for div1 in div:
try:
h3 = div1.find_all('h3')
for h in h3:
course_name = h.string
course_url = course_start_url + href
span = div1.find_all('span')
person_num_part = re.compile(r'.*?(.*?)',re.S)
course_drank = span[0].string
course_number = re.findall(person_num_part, str(span[1]))[0]
course_introduction = div1.find_all('p')[0].string
course_price = span[2].string
course_item = [course_name, course_url, course_price, course_drank, course_number, course_introduction]
if course_name.strip() != '':
clist.append(course_item)
except:
continue
def coursePrint(clist):
tplt = "{0:{6}^10}\t{1:{6}^10}\t{2:{6}^10}\t{3:{6}^10}\t{4:{6}^10}\t{5:{6}^10}"
print(tplt.format("课程名称", "课程链接", "课程价格", "课程级别", "参加人数", "课程介绍", chr(12288)))
for courseList in clist:
print(tplt.format(courseList[0], courseList[1], courseList[2], courseList[3], courseList[4], courseList[5], chr(12288)))
def writexls(clist):
output = open('慕课课程.xls', 'w', encoding='gbk')
output.write('课程名称\t课程链接\t课程价格\t课程级别\t参加人数\t课程介绍\n')
for i in range(len(clist)):
for j in range(len(clist[i])):
output.write(str(clist[i][j])) # write函数不能写int类型的参数,所以使用str()转化
output.write('\t') # 相当于Tab一下,换一个单元格
output.write('\n') # 写完一行立马换行
output.close()
def writetxt(clist):
output = open('慕课课程.txt', 'w', encoding='gbk')
tplt = "{0:{6}^10}\t{1:{6}^10}\t{2:{6}^10}\t{3:{6}^10}\t{4:{6}^10}\t{5:{6}^10}"
output.write(tplt.format("课程名称", "课程链接", "课程价格", "课程级别", "参加人数", "课程介绍", chr(12288)))
for courseList in clist:
output.write(tplt.format(courseList[0], courseList[1], courseList[2], courseList[3], courseList[4], courseList[5], chr(12288)))
output.write('\n') # 写完一行立马换行
output.close()
def main():
start_url = 'http://www.imooc.com/course/list?page='
courseList = []
for i in range(30):
c_url = start_url + str(i)
html = getTHMLText(start_url)
parserHTML(html,courseList)
# coursePrint(courseList)
writexls(courseList)
# writetxt(courseList)
main()
getTHMLText(url),获取url链接中的内容为html结构。
parserHTML(html, clist), 负责解析html页面中的内容,用于提取课程名称,课程链接,课程价格, 课程级别,参加人数, 课程介绍。
在查看网页元代码之后可以发现课程链接位于a标签的href属性中,而课程名称是a标签下的div标签中的h3标签中的文本。而课程级别, 参加人数,课程价格位于div标签下的span标签中,使用div.find_all(‘span’),可以发现结果中存在四个结果,第一个结果的string是课程级别, 第二个结果的string是参加人数,第三个结果的string是课程价格。其中在提取参加人数的时候如果直接使用string会出现问题,所以使用re正则表达式进行匹配。
r'.*?(.*?)'
用于匹配</i></span>之间的字符。
课程介绍位于p标签下。在完整提取了所有的内容之后,将所有内容放入一个列表,然后在将列表加入clist中。
coursePrint(clist),用于打印爬取的所有内容,虽然在程序中使用了格式化对齐,但是,由于内容的数量,依旧不能很好的输出爬取的数据。所以还编写了writexls(clist), 用于将爬取的数据保存到excel表格中,此外还编写了writetxt(clist)方法用于将爬取的数据写入txt文件中。在main方法中实现了循环爬取30页内容数据。
结果如图所示: