简单利用python爬取网站数据
import requests
page=requests.get('https://www.baidu.com/')
print(page.text)
首先就是这最简单的这三行python代码
import request导入我们需要的功能模块,request的功能就是我们向互联网发送请求和获取数据的
page=requests.get(‘https://www.baidu.com/’)这句就是表示获取百度网站首页的数据
print(page.text)把我们获取到的网页数据输出出来
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>ç¾åº¦ä¸ä¸ï¼ä½ å°±ç¥é</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129>
//...........
可以看到,将网页的信息打印了出来,就是要从网页的源码信息中,提取出我们需要的信息
这里以豆瓣电影TOP250网页为例
# -*- coding: utf-8 -*-
import requestshaiyou
from lxml import etree
from bs4 import BeautifulSoup
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}
start=0
f=open('/home/android/tmp/1.txt','a+')
for n in range(0,10):
html = requests.get("https://movie.douban.com/top250?start="+str(start),headers=headers)
start += 25
soup = BeautifulSoup(html.text, 'html.parser')
for item in soup.find_all('div',"info"):
title = item.div.a.span.string # 获取标题
yearline = item.find('div', 'bd').p.contents[2].string
yearline = yearline.replace(' ', '') # 去掉这一行的空格
yearline = yearline.replace('\n', '') # 去掉这一行的回车换行
year = yearline[0:4] # 只取年份前四个字符
print(title+'\t'+year)
f.write(title+'\t'+year+'\n')
f.close()
上面的代码解释的话就是
# -*- coding: utf-8 -*-
如果要在python2的py文件里面写中文,则必须要添加一行声明文件编码的注释,否则python2会默认使用ASCII编码。
import requests
from lxml import etree
from bs4 import BeautifulSoup
import sys
这是导入需要的功能模块,from bs4 import BeautifulSoup的意思就是bs4不需要全部导入,只需要其中的BeautifulSoup模块
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
是解决在文件写入时,非ascii编码报错的问题, python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0x?? in position 1: ordinal not in range(128),python没办法处理非ascii编码的,此时需要自己设置将python的默认编码,一般设置为utf8的编码格式。
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}
这是在获取网站信息的时候添加的头部信息,因为一些网站拥有反爬虫机制,一些网站会根据headers来判断是否是爬虫,所以我们要伪装headers信息。如果是通过requset来请求网站的话,
例如:
import requests
html = requests.get("https://blog.csdn.net/it_xf?viewmode=contents")
print(html.request.headers)
得到的结果是:
{'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'python-requests/2.23.0'}
而像豆瓣这种具有判断爬虫机制的网站,右键检查–>network,刷新一下,看它的herdaers
所以我们想要绕开这个反爬措施的时候,就要将自己伪装成游览器,将他的headers替换自己的headers,然后添加到请求后面
html = requests.get("https://movie.douban.com/top250?start="+str(start),headers=headers)
start=0
f=open('/home/android/tmp/1.txt','a+')
for n in range(0,10):
html = requests.get("https://movie.douban.com/top250?start="+str(start),headers=headers)
start += 25
soup = BeautifulSoup(html.text, 'html.parser')
for item in soup.find_all('div',"info"):
title = item.div.a.span.string # 获取标题
yearline = item.find('div', 'bd').p.contents[2].string
yearline = yearline.replace(' ', '') # 去掉这一行的空格
yearline = yearline.replace('\n', '') # 去掉这一行的回车换行
year = yearline[0:4] # 只取年份前四个字符
print(title+'\t'+year)
f.write(title+'\t'+year+'\n')
f.close()
这后面的主要就是主要的功能代码,f=open('/home/android/tmp/1.txt','a+')
,打开一个1.txt文件,如果没有就创建,模式是a+,
模式 | 可做操作 | 若文件不存在 | 是否覆盖 |
---|---|---|---|
r | 只可读 | 报错 | - |
r+ | 可读可写 | 报错 | 是 |
w | 只可写 | 创建 | 是 |
w+ | 刻度可写 | 创建 | 是 |
a | 只可写 | 创建 | 否,追加 |
a+ | 可读可写 | 创建 | 否,追加 |
for n in range(0,10):
循环,range(0,10)是生成一个0-9的集合
soup = BeautifulSoup(html.text, 'html.parser')
BeautifulSoup是bs4里面的功能模块,这里就是调用html的parser(解析器),来解析我们获取的网页html的文字内容,soup就是解析的结果。
for item in soup.find_all('div',"info"):
这里又是一个循环,在我们获得了解析到的网页内容后,调用soup的find_all方法来查找全部,查找全部标记名为div,class的值是info的元素的值
title=item.div.a.span.string
中item代表的是上面图片中的整个div
元素(class=’info’),它的下一层div的下一层a的下一层span的“肖申克的救赎”就是我们需要的内容,但是一层层的点下去的方法只适合于获取到每层的第一个元素,比如我们知道实际有三个span,其他两个英文名、其他译名,但我们只取到第一个。
yearline = item.find('div', 'bd').p.contents[2].string
就是调用了.find,.p方法,contents[2]
是取得这一行第3个文字小节,content单词是内容的意思, br
标记将整个p
标记内容分成了三段(0段,1段,2段)。
f.write(title+'\t'+year+'\n')
将内容写入文件中
肖申克的救赎 1994
霸王别姬 1993
阿甘正传 1994
这个杀手不太冷 1994
美丽人生 1997
泰坦尼克号 1997
千与千寻 2001
辛德勒的名单 1993
盗梦空间 2010
忠犬八公的故事 2009
海上钢琴师 1998
楚门的世界 1998