用Python写爬虫是很方便的,最近看了xlzd.me的文章,他的文章写的很到位,提供了很好的思路。因为他的文章部分代码省略了。下面是基于他的文章的三个代码片段:
基于Python3,Python2的话需要修改下input输入函数和print的用法。本文github代码地址

  1. 爬取豆瓣电影top250

  2. 爬取拉勾网职位信息

  3. 模拟登陆知乎

  4. 为什么没人给我点赞。?!

有些代码做了更改。其中把获取的数据存储到excel中。关于存取数据到excel可以看我的另一篇文章:

用到的库

  • requests

  • Beautiful Soup

  • openpyxl

1. 爬取豆瓣电影top250,存到excel表格中

#!/usr/bin/env python
# encoding=utf-8
import requests,re
import codecs
from bs4 import BeautifulSoup
from openpyxl import Workbook
wb = Workbook()
dest_filename = '电影.xlsx'
ws1 = wb.active  
ws1.title = "电影top250"

DOWNLOAD_URL = 'http://movie.douban.com/top250/'

def download_page(url):
    """获取url地址页面内容"""
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36'
    }
    data = requests.get(url, headers=headers).content
    return data


def get_li(doc):
    soup = BeautifulSoup(doc, 'html.parser')
    ol = soup.find('ol', class_='grid_view')
    name = [] #名字
    star_con = [] #评价人数
    score = []  #评分
    info_list = []  #短评
    for i in ol.find_all('li'):
        detail = i.find('div', attrs={'class': 'hd'})
        movie_name = detail.find('span', attrs={'class': 'title'}).get_text() #电影名字
        level_star = i.find('span',attrs={'class':'rating_num'}).get_text() #评分
        star = i.find('div',attrs={'class':'star'})
        star_num = star.find(text=re.compile('评价'))  #评价

        info = i.find('span',attrs={'class':'inq'})  #短评
        if info:     #判断是否有短评
            info_list.append(info.get_text())
        else:
            info_list.append('无')
        score.append(level_star)
        

        name.append(movie_name)
        star_con.append(star_num)
    page = soup.find('span', attrs={'class': 'next'}).find('a') #获取下一页
    if page:
        return name,star_con,score,info_list,DOWNLOAD_URL + page['href']
    return name,star_con,score,info_list,None


def main():
    url = DOWNLOAD_URL
    name = []
    star_con=[]
    score = []
    info = []
    while url:
        doc = download_page(url)
        movie,star,level_num,info_list,url = get_li(doc)
        name = name + movie
        star_con = star_con + star
        score = score+level_num
        info = info+ info_list
    for (i,m,o,p) in zip(name,star_con,score,info):
        col_A = 'A%s'%(name.index(i)+1)
        col_B = 'B%s'%(name.index(i)+1)
        col_C = 'C%s'%(name.index(i)+1)
        col_D = 'D%s'%(name.index(i)+1)
        ws1[col_A]=i
        ws1[col_B] = m
        ws1[col_C] = o
        ws1[col_D] = p
    wb.save(filename=dest_filename)

if __name__ == '__main__':
    main()

结果如下:

2. 爬取拉勾网Python职位信息

职位信息存储在json中,获取到json对象,再从中遍历出公司名、地址、待遇等信息。

import requests
from openpyxl import Workbook

def get_json(url, page, lang_name):
    data = {'first': 'true', 'pn': page, 'kd': lang_name}
    json = requests.post(url, data).json()
    list_con = json['content']['positionResult']['result']
    info_list = []
    for i in list_con:
        info = []
        info.append(i['companyShortName'])
        info.append(i['companyName'])
        info.append(i['salary'])
        info.append(i['city'])
        info.append(i['education'])
        info_list.append(info)
    return info_list


def main():
    lang_name = input('职位名:')
    page = 1
    url = 'http://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
    info_result = []
    while page < 31:
        info = get_json(url, page, lang_name)
        info_result = info_result + info
        page += 1
    wb = Workbook()
    ws1 = wb.active
    ws1.title = lang_name
    for row in info_result:
        ws1.append(row)
    wb.save('职位信息.xlsx')

if __name__ == '__main__':
    main()

运行结果:

3. 模拟登录知乎

通过开发者工具,获取post的数据。

import requests,time
from bs4 import BeautifulSoup
def get_captcha(data):
    with open('captcha.gif','wb') as fp:
        fp.write(data)
    return input('输入验证码:')

def login(username,password,oncaptcha):
    sessiona = requests.Session()
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'}
    _xsrf = BeautifulSoup(sessiona.get('https://www.zhihu.com/#signin',headers=headers).content,'html.parser').find('input',attrs={'name':'_xsrf'}).get('value')
    captcha_content = sessiona.get('https://www.zhihu.com/captcha.gif?r=%d&type=login'%(time.time()*1000),headers=headers).content
    data = {
        "_xsrf":_xsrf,
        "email":username,
        "password":password,
        "remember_me":True,
        "captcha":oncaptcha(captcha_content)
    }
    resp = sessiona.post('https://www.zhihu.com/login/email',data,headers=headers).content
    print(resp)
    return resp 

if __name__ == "__main__":
    login('your_email','your_password',get_captcha)

运行后会在运行目录下得到验证码图片:

输入验证码后得到如下响应结果表明登录成功。

你可能感兴趣的文章

本作品 保留所有权利 。未获得许可人许可前,不允许他人复制、发行、展览和表演作品。不允许他人基于该作品创作演绎作品 。

31 条评论
月月bird · 1月7日

解决了,一个是用浏览器访问一下,然后把所有的header内容都传给requests就可以了好像拉钩为了防止爬虫加了个cookie我想应该是这样,因为这里token每次都是变化的,必须有这个token才能访问。其次info.append(i['companyName'])这个语句有问题,去掉,就可以正常工作了。

+1 回复

lsz8oq · 2016年07月25日

写的真好,谢谢。

回复

InjetLee 作者 · 2016年07月25日

??点个赞再走。我也是在学习中。有问题给我留言

回复

lsz8oq · 2016年07月25日

声望不够。。

回复

InjetLee 作者 · 2016年07月26日

哈哈,赶紧的,赚点声望

回复

fszhuangb · 2016年10月12日

你好,我在做拉钩网招聘信息的爬取,但我在用chrome的开发者选项查看网络信息的时候,找不到positionAjax.json这个文件了啊,不知道是不是拉钩网的信息显示机制变了呢?

回复

InjetLee 作者 · 2016年10月12日

我刚看了一下,有这个请求。你在好好看看。我用的是firefox。这个和浏览器没有关系。

回复

fszhuangb · 2016年10月12日

好的,我初学爬虫,还有很多不懂的~谢谢你的回复??

回复

InjetLee 作者 · 2016年10月12日

找不到了,再给我留言。

回复

fszhuangb · 2016年10月12日

好的好的谢谢

回复

fszhuangb · 2016年10月13日

谢谢lz,我已经完全弄明白了,请问还有什么像拉勾网这样异步加载的网站吗?我想多爬几个练练手

回复

InjetLee 作者 · 2016年10月14日

这个没找过。

回复

ffandcc · 2016年10月24日

请问一下,为什么我抓取豆瓣TOP250时,写到文件里一总只有243个值?楼主有这样的情况吗?

回复

wahson丶 · 2016年11月25日

遇到那种拖动拼图的验证码识别咋办

回复

InjetLee 作者 · 2016年11月25日

那个我也没研究过。

回复

wahson丶 · 2016年11月25日

这就尴尬了

回复

月月bird · 1月7日

爬去拉钩出现了json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)错误请问是为什么?

回复

InjetLee 作者 · 1月7日

我刚看了一下,拉勾应该是改过什么地方了,思路是这样的。很简单。学习下思路,你多看一下requests的文档。

回复

月月bird · 1月7日

我正在研究,写的语法应该是没问题的,但是拉钩发现是post发送的消息,就是非浏览器的发送的偶会认为是爬虫行为,所以就会组织,不过现在还不知道是用什么来判断的

回复

InjetLee 作者 · 1月7日

拉勾拉勾是增加了浏览器验证,我试着加了请求头,还是没通过,直接forbidden了。

回复

载入中...
InjetLee InjetLee

459 声望

发布于专栏

Python提高班

技术,生活。

13 人关注