例1:
爬取抽屉新热榜示例:
有些网站没有任何反爬机制,如汽车之家,任何人来了都能爬取,而有些网站设置了反扒机制,如
import requests
response = requests.get('https://dig.chouti.com/')
print(response.text)
运行结果
不能获取到网页内容,因为伪装成浏览器时不像浏览器,而发送请求本质是发送请求头和请求体。
看看网络的请求头信息:
如果能像浏览器那样发送以上数据,就分别不出是代码还是浏览器,就能获取到response
import requests
response = requests.get(
url = 'https://dig.chouti.com/',
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'}
) # user-agent:用什么设备发送请求
print(response.text)
运行结果
一般携带user-agent就行了,还有一些网站需要带hosts,或者别的,可以一个一个放到get的参数中,最后肯定能成功,因为和浏览器一模一样的了
需要获取的内容
所有列表显示时是模版语言做的for循环,所以每个样式都是一样的。找到一个后就可以找到列表中所有内容
import requests
from bs4 import BeautifulSoup
response = requests.get(
url = 'https://dig.chouti.com/',
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'}
) # user-agent:用什么设备发送请求
soup = BeautifulSoup(response.text, 'html.parser') # 把字符串变成对象(html标签),对象中嵌套对象,通过标签名找到该对象
content_list = soup.find(name='div', id='content-list') # 找到第一个标签对象,只有标签对象才能往下find或find_all
item_list = content_list.find_all(name='div', attrs={'class':'item'}) # 列表,列表中为每个便签对象,标签对象可以使用find和find_all方法
for item in item_list:
a = item.find(name='a', attrs={'class':'show-content color-chag'}) # 在对象的子子孙孙中找到第一个a标签
print(a.text.strip())
运行结果
例2:
点赞
由于登录后才能点赞,所以要先登录,登录时如果没有刷新发的ajax请求,如
需模拟浏览器,给Requset_URL这个地址发送POST请求,
import requests
# 提交用户名和密码
r2 = requests.post(
url='https://dig.chouti.com/login',
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'},
data={
'phone': 861868211xxxx,
'password': 123456,
'oneMonth': 1
}
)
print(r2.text)
运行结果
{"result":{"code":"9999", "message":"", "data":{"complateReg":"0","destJid":"cdu_55342938396"}}}
返回9999证明登录成功,浏览器返回cookie值,再此访问该网站时带着cookie值就知道是这个人。所以需接收cookie,以后带着这个cookie点赞。
再浏览器点赞时往某个网站发数据,如
模拟往以上地址发送post请求
import requests
# 提交用户名和密码
r2 = requests.post(
url='https://dig.chouti.com/login',
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'},
data={
'phone': 8618682113761,
'password': 123456,
'oneMonth': 1
}
)
cookie_dict = r2.cookies.get_dict() # 把返回的cookie当作字典
# 点赞
r3 = requests.post(
url='https://dig.chouti.com/link/vote?linksId=25318941', # 要点赞的文章信息
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'},
cookies=cookie_dict, # 带着cookie访问网站,网站去数据库的session拿用户信息。
)
print(r3.text)
运行结果
没有点赞成功,返回了首页,有些网站只要拿到成功登录时的cookie再用这个cookie发给网站就可以找到用户信息,而有些往站登录成功后发送的一个假的cookie,这个cookie没有用,如果没有访问首页就直接post点赞肯定是爬虫,而正常的步骤是先访问首页再登录后点赞。而抽屉是当浏览器访问首页或任何页面时直接放回了一个cookie的随机字符串,此时没有登录,后台的session是空的,这个cookie没有经过授权,再次登录时把这个cookie带过来,对cookie进行授权,就生效了。
import requests
# 访问首页
r1 = requests.get(
url = 'https://dig.chouti.com/',
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'}
)
r1_cookie = r1.cookies
# 提交用户名和密码
r2 = requests.post(
url='https://dig.chouti.com/login',
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'},
data={
'phone': 8618682113761,
'password': 123456,
'oneMonth': 1
},
cookies=r1_cookie.get_dict() # cookies授权成功
)
cookie_dict = r2.cookies.get_dict() # 把返回的cookie当作字典,这个cookie是为了混淆用户
# 点赞
r3 = requests.post(
url='https://dig.chouti.com/link/vote?linksId=25317651', # 要点赞的文章信息
headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'},
cookies=r1_cookie.get_dict(), # 带着cookie访问网站,网站去数据库的session拿用户信息。
)
print(r3.text)
运行结果
{"result":{"code":"9999", "message":"推荐成功", "data":{"jid":"cdu_55342938396","likedTime":"1553431342485000","lvCount":"27","nick":"jalsdkjf","uvCount":"5","voteTime":"小于1分钟前"}}}
而爬虫就是使用浏览器的network进行不断测试才明白某个网站用的什么套路。
实例三:自动登录github
首先看网页的运行规则:
拿到login页面中的authenticity_token
.点击登录时,往session页面携带了第一次访问登录页面时返回的authenticity_token,
import requests
from bs4 import BeautifulSoup
# 访问登录页面时获取cookie(未授权)并找到隐藏的input标签获取csrf_token,
i1 = requests.get('https://github.com/login')
soup1 = BeautifulSoup(i1.text, 'html.parser')
tag = soup1.find(name='input', attrs={'name': 'authenticity_token'})
authenticity_token = tag.get('value')
c1 = i1.cookies.get_dict()
i1.close()
# 点击登录时为form表单向后台发送post请求,携带authenticity_token和用户名密码等信息,发送用户验证,Django中发送POST请求都要发送csrf_token,携带cookie,并拿到第二次返回的cookie,此cookie可直接登录网页,
form_data = {
"authenticity_token": authenticity_token,
"utf8": "✓",
"commit": "Sign in",
"login": "[email protected]",
'password': 'xxxx'
}
i2 = requests.post('https://github.com/session', data=form_data, cookies=c1) # 提交post请求,携带authenticity_token和第一次返回的cookie
c2 = i2.cookies.get_dict() # 拿到登录成功后第二次返回的cookie
c1.update(c2) # 更新第一次的cookie
i3 = requests.get('https://github.com/settings/repositories', cookies=c1) # 携带登录后的cookie值,拿到用户repositories数据
soup3 = BeautifulSoup(i3.text, 'html.parser')
list_group = soup3.find(name='div', class_='listgroup')
from bs4.element import Tag
for child in list_group:
if isinstance(child, Tag):
project_tag = child.find(name='a', class_='mr-1')
size_tag = child.find(name='span', class_='text-small')
temp = "项目:%s(%s); 项目路径:https://github.com/%s" % (project_tag.text, size_tag.text.strip().split('\n', 1)[0], project_tag.text )
print(temp)
运行结果
示例4:自动登录拉勾网
登录拉钩网是密码是加密的
由于使用js实现加密,首先找到js代码,看看加密方法是什么,再用python自己实现。也可以直接拿到这个已经转换好的密文直接发送过去就可以了,
拉钩在登录页面返回时在请求体中携带了动态token,点击登录时需携带该随机token发送post请求,相当于csrf_token,所以第一次发get请求时拿到这个随机值,而且没有嵌套在html标签中,不能使用Beauitifullsoup,只能自己写正则。才可以登录成功
在这里插入代码片