Web Scraping数据抓取
Get HTML 的response内容
response.content
response = requests.get("http://dataquestio.github.io/web-scraping-pages/simple.html")
content = response.content
print(content)
output:
image.png
BeautifulSoup 框架
引入框架
from bs4 import BeautifulSoup
拿上面的content内容来解释
image.png
要访问HTML的内容,首先生成一个页面分析对象,即parser,然后如果要取内部的标签,需要层层向下层的branch中取,好似一个大树,如取title tag,取p tag代码如下
parser = BeautifulSoup(content, 'html.parser') //生成parser分析对象,content为上文requests get到的页面内容
title_text = parser.head.title.text
p_text = parser.body.p.text
find_all
- 但是不是所有的标签内容都是只有一个同类标签,可能html下面有10个head标签,所以要想get所有的标签不出现混乱,我们使用find_all()函数,以取到html下的第一个head标签为例, parser.find_all("head"),返回一个包含全部head元素的list。
parser = BeautifulSoup(content,'html.parser')
head = parser.find_all("head")
title = head[0].find_all("title")
title_text = title[0].text
print(title_text)
- find_all也可以带参数id,id可直接定位到要找的标签页,不需要再一层一层寻找下层标签,但定位后仍然需要用[0]跟上因为find_all必定返回list,如寻找如图 id second内容
image.png
second_paragraph_text = parser.find_all("p",id = "second")[0].text
- find_all也可以使用class_来直接访问内部标签的元素,class标注了一种类型的数据,如photo,image,inner_text这种类型定义形式同ID,如图
image.png
如访问第二个的outer-text内容代码如下,其中<b></b>标签就不在进行元素查找,直接text即可得内容
second_outer_text = parser.find_all("p",class = "outer-text")[1].text
CSS(Cascading Style Sheets)
css用来给页面渲染样式,有机几种标签组合方式
- 所有p标签上红色
p{
color: red
}
- 所有p标签inner-text类红色,类使用.
p.inner-text{
color: red
}
- 所有p标签ID为first标红
p#first{
color: red
}
- 所有ID为first标红
#first{
color: red
}
- 所有inner_test类标红
.inner-text{
color: red
}
.select 方法用来按照类和ID名称选取parser中的相关内容
- 选择类的所有元素使用.inner-text
- 选择ID的所有元素使用#second
first_outer_text = parser.select(".outer-text")[0].text
second_text = parser.select("#second")[0].text
select的选取范围有无穷多种,以下几个例子如
- 选取所有div下的p标签
div p
- 选取div下的first_item类
div .first-item
- 选取body下所有div下ID为first的元素
body div #first
- 选取所有first-item类方法元素下ID为first的元素
.first-item #first
select二次选择
image.png
- 如图选择Seattle Seahawks队total-yards数量和New England Patriots 的total-plays,注意select之后也是list,要接[]
total_players = parser.select("#total-plays")[0]
patriots_total_plays_count = total_players.select("td")[2].text
print(patriots_total_plays_count)
seahawks_total_yards_count = parser.select("#total-yards")[0].select("td")[1].text
print(seahawks_total_yards_count)
安装Beautifulsoup
Beautifulsoup不是python的标准库,所以需要安装其最新版本Beautiful4(BS4),安装方法在http://www.crummy.com/software/BeautifulSoup/bs4/doc/里面。
- Linux的安装方法为
pip3 install beautifulsoup4
- window的安装方法
到c:\Users\XXX\AppData\Local\Programs\Python\Python36\Scripts\目录下执行
pip install beautifulsoup4
鉴于我们大部分linux机器不能联通外网,可以先下载bs4的安装包,由于下载的代码是适应python2安装的,如果是python3环境所以要先执行以下2to3,如果你用python2就不需要了。https://www.crummy.com/software/BeautifulSoup/bs4/download/4.6/
4.6版本最新
tar -zxvf beautifulsoup4-4.6.0.tar.gz
cd beautifulsoup4-4.6.0
cp /usr/python3/bin/2to3 .
./2to3 -w bs4
python3 setup.py install
安装后import以下如果没有报错就说明安装成功了
python3
>>from bs4 import BeautifulSoup
>>
urllib.parse
urlparse()函数可以将url分割为6部分,对于要分别提取url各个部分的需求是极为好用的函数,具体6部分为
- scheme url的头部分,一般为http
- netloc (network location)url的主域名部分,一般为//到/之间的内容,
- path 主域名之后的部分.html
from urllib.parse import urlparse
o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
params='', query='', fragment='')
print(o.scheme,o.netloc,o.path)
使用Scrapy采集
- 安装Scrapy
在window上安装Scrapy很简单,locate到pip的根目录下可以直接使用pip install scrapy即可,现在最新版本的scrapy 1.5 可以直接在python2.7|3.4以上的环境上运行无障碍,以前的版本只能在2.7上,网站为https://scrapy.org/download/可以查看一些1.5版本具体的介绍。
image.png
windows运行pip install scrapy后可能出现报错如图,看提示是缺少了VC++ 14.0,去http://landinghub.visualstudio.com/visual-cpp-build-tools微软官网去找。
image.png
- 在这个页面https://www.visualstudio.com/zh-hans/downloads/?rr=https%3A%2F%2Fwiki.python.org%2Fmoin%2FWindowsCompilers下载左边这个即可
image.png
我安装了这几个
image.png
然后后续还会出现安装编码问题在windows上
image.png
然后在自己的python目录下Python\Python36\Lib\site-packages\pip\compat_init_.py修改return s.decode('utf_8') 改为return s.decode('cp936'),如果出现PermissionError: [WinError 5]修改为管理员模式运行cmd就行了
- 运行scrapy crawl article时候还是会报错
image.png
需要继续安装
pip install pypiwin32
抓取twitter数据
Twitter是一个数据金矿。不像其他的社交平台,几乎每个Twitter用户的微博都是完全开放并且是可拉取的。如果你想尝试获取大量的数据然后对其进行分析,这是相当有帮助的。同时,Twitter的数据也是非常具体的。它的API接口允许你进行复杂的查询,例如拉取最近20分钟内关于指定某个话题的每一条微博,或者是拉取某个用户非转发的微博。
使用Tweepy
image.png
Tweepy是twitter提供的一个python库,用来访问twitter的API接口,官方地址http://www.tweepy.org/,可以阅读下官方Docs了解细节。
- 安装方法非常简单,只需
pip install tweepy
如果在linux系统上可以通过git安装,先安装git,然后
git clone https://github.com/tweepy/tweepy.git
cd tweepy
python setup.py install
- 注册twitter账号
登陆https://twitter.com/注册账号,不要注销账号 - 注册开发者账号
继续登陆https://apps.twitter.com/,new一个app账号,用户名唯一就行
image.png
image.png -
查看自己的token
注册成功我们能查询到自己的consumer Key,consumer Secret,Access Token,Access Token Secret,这几个参数用来访问时候认证和授权,不要泄露出去
image.png
抓取整个页面
下面我们来抓取整个页面信息,使用home_timeline()函数
import tweepy
consumer_key = ""#填上自己的keys
consumer_secret = ""
access_token = ""
access_token_secret = ""
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token,access_token_secret)
api = tweepy.API(auth)#代入API的keys参数
public_tweets = api.home_timeline()#取当前时间首页的所有内容
for tweet in public_tweets:
print(type(tweet),type(api))
print(tweet,tweet.text,tweet.created_at,tweet.user.screen_name,tweet.user.location)#text表述了twitter的文字内容及链接,created_at是创建的时间,可以看到各种属性值,user.下的screen_name表示了用户名,location表示了地理坐标,如果你对位置敏感一定要关注这个信息
可以看到api类型是tweepy库API类,这个类的具体参数如下图
api
image.png
在后来我们打印出微博的text,可以看到这里包含了我的twitter主页上的微博内容极其链接,时间,地点,看一下内容和我的首页是一样的,我其实挺后悔关注trump的。。弄得一脸都是
微博内容
image.png
抓取指定用户的微博内容
image.png
通过user_timeline函数能够抓取指定id用户的可控数量的微博,下面是函数的介绍,
我们抓取钢铁侠的最近20条微博,以及他的全部用户信息
Robert = api.user_timeline(screen_name = "RobertDowneyJr",count = 20 )#
for tweet in Robert:
print(tweet.text)
users = api.get_user(id = "RobertDowneyJr")#能够取到该用户的所有信息
print(users)
-
如图位置我们可以取到用户的screen_name
image.png -
我们也可以从user信息里看到他的全部信息
image.png
最后我们使用search()函数按照指定query查询微博,q和lang分别指查询query和给明的语言,如果不加lang会出现很多日语,阿拉伯语的微博,我们来搜索一下最近中兴事件的相关微博。
image.png
ZTE = api.search(q = "ZTE",lang = "en")
for item in ZTE:
print(item.text)
image.png
使用google API
image.png
google的各种API可以为我们提供非常多的抓取机会,比如地图位置,邮件,社交,google drive,机器学习,翻译,youtube等等,最常用的我们在app里经常嵌套google地图,我们可以通过google提供给我们的API免费key来调用各种服务API,获取我们想要的信息
- 首先我们需要注册一个google账号,访问https://accounts.google.com/SignUp
- 然后需要创建自己的API key 访问https://console.developer.google.com/
-
在凭据页面创建自己的凭据,创建凭据时需要先选择一个API类型,我们选择API webService查询地址
image.png
image.png
下面代码我们分别查询科学公园,北京时区,白宫地址
import requests
import json
response = requests.get("https://maps.googleapis.com/maps/api/geocode/json?address=1+Science+Park+Boston+Ma+02114&key = <>")#address地点我们填写马萨诸塞州波士顿市科学公园1号
data = response.json()
print(data,"\n")
response2 = requests.get("https://maps.googleapis.com/maps/api/timezone/json?location=39.92,116.46×tamp=1412649030&key =<>")
data2 = response2.json()
print(data2,"\n")
response3 = requests.get("https://maps.googleapis.com/maps/api/geocode/json?address=The White House+Washington D.C&key = <>")#直接输入了白宫的address,找到了宾夕法尼亚大街1600号
data3 = response3.json()
print(data3)
response4 = requests.get("https://maps.googleapis.com/maps/api/elevation/json?locations=42.3677994,-71.0708078&key = <>")
data4 = response4.json()
print(data4)
google的API能够自动识别白宫,找到其对应的门牌号宾夕法尼亚大街1600号;同时按照北京的经纬度获得了上海时区识别,指定地点海拔5米