Python 爬虫专栏@IT·互联网Python爬虫作业

python爬虫——知乎(关于python的精华回答)

2017-05-02  本文已影响1006人  loading_miracle

<strong>之前的文章都是与职位、热门文章有关的,今天一起来看一下知乎上与python相关的精华回答(主要是requests,scrapy处理的思路,编码问题)</strong>

知乎python精华回答

1.采集的信息

<ol>
<li>问题题目</li><li>问题对应URL</li><li>回答的作者</li><li>作者主页URL</li><li>回答获赞数</li><li>回答详情URL</li></ol><strong>主要获取以上信息,接着我们来看一下这些字段所在的位置

字段位置

通过观察和分析以上字段在源码中都能找到,所以就不用像前几篇文章那样,构造参数,解析获取返回的json数据,我们可以通过lxml.etree.HTML()或者Beautifulsoup去解析(这里在通过etree解析时遇到了一些问题,在后边会进行解释)
既然不需要通过构造参数去获取数据了,所以相对来说就简单一些了,接下来我们来看一下另一个很重要的问题——分页问题</strong>

第一页 第二页

<em>从上面两张图片我们可以看出换页之后参数<strong>page</strong>发生了改变,很显然<strong>page</strong>控制的是页码,明白了这一点就可以去构造URL了</em>

2.构造URL

总页数
urls = ['https://www.zhihu.com/topic/19552832/top-answers?page={}'.format(one) for one in range(1,51)]

<strong>解决了分页问题,就没什么难点了,接下来说一下遇到的问题和解决方法

# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
from store_csv import CSV
from store_mysql import Mysql
class zhiHu(object):
    baseurl = 'https://www.zhihu.com'
    headers = {
        "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"
    }
    cookies = {
        'd_c0': '"AHACIj6lFguPTkEZTVmz8MPJ8UkcuI03hag=|1483278273"',
        '_zap': '108369f2-93e6-407e-8928-b57f44168838',
        'q_c1': '0d3d690c67bc4b12a163beb462e17d67|1492571575000|1483278273000',
        'cap_id': '"NmFlNDgyZmMxNWQ0NGFiYmFhZThmMGM2MDVkZDM1MWM=|1493684435|1958b2bb9fb6f09116056cc4bc5af76e00dbaff7"',
        'l_cap_id': '"ZjViYmQ0MzBkNTFjNGJjOWE5YTExZWRjMjlkNjM2YjQ=|1493684435|1204e5c054805d8bebf3b49a8a2fc09e2f1bd870"',
        'auth_type': '"c2luYQ==|1493684515|245a0f575f151c486829c687ba3d3c90fc5fa558"',
        'token': '"Mi4wMGljWjNYRkVBNzIyRGJjZDZkMjMyZmMwM2JtMWs=|1493684515|a76491c048b7e825a77983ef0a272bdc9e721853"',
        'client_i': '"NTA3MzY2MzQwNA==|1493684515|9a08a2c9a6c02e86da4810cb5bc4437f6d7b1028"',
        'aliyungf_tc': 'AQAAAFOsE04F5QQAHVcc2i2qHTGdX1x0',
        'acw_tc': 'AQAAAAnnBnQS0AcAHVcc2omDblHld+wt',
        '_xsrf': '398e0b041f39355dadfc06b76ba18cdb',
        's-q': 'python',
        's-i': '1',
        'sid': 'ob2ttqkg',
        's-t': 'autocomplete',
        'z_c0': 'Mi4wQUFBQ3hmbTFzUXNBY0FJaVBxVVdDeGNBQUFCaEFsVk5OVjR2V1FETW9QS19PRlExWGVjUHNOcFVoTG5mYWg1LUtR|1493701061|4258e8f2ddc800c42c8b7d94385f578ca97f34d5',
        '__utma': '51854390.213172690.1484833633.1493684449.1493701029.4',
        '__utmb': '51854390.0.10.1493701029',
        '__utmc': '51854390',
        '__utmz': '51854390.1493701029.4.4.utmcsr=baidu|utmccn=(organic)|utmcmd=organic',
        '__utmv': '51854390.100--|2=registration_date=20170502=1^3=entry_date=20170101=1'
    }
    def getUrl(self):
        urls = ['https://www.zhihu.com/topic/19552832/top-answers?page={}'.format(one) for one in range(1,51)]
        for url in urls:
            self.getData(url)
    def getData(self,url):
        data = requests.get(url, headers=self.headers, cookies=self.cookies).content.encode('utf-8')
        soup = BeautifulSoup(data, 'lxml')
        infos = soup.find_all('div', {'class': 'feed-item feed-item-hook folding'})
        item = {}
        for info in infos:
            item[1] = info.find('a',{'class':'question_link'}).get_text().strip()
            item[1] = item[1].replace("'","=")
            item[2] = self.baseurl+info.find('a',{'class':'question_link'}).get('href')
            try:
                item[3] = info.find('a',{'class':'author-link'}).get_text()
            except:
                item[3] = u'匿名用户'
            try:
                item[4] = self.baseurl+info.find('a',{'class':'author-link'}).get('href')
            except:
                item[4] = u''
            item[5] = info.find('a',{'class':'zm-item-vote-count js-expand js-vote-count'}).get_text()
            try:
                item[6] = self.baseurl+info.find('a',{'class':'toggle-expand'}).get('href')
            except:
                item[6] = u''
            self.store(item)
    def store(self,item={}):
        #row = [item[i] for i in range(1,7)]
        #wirte.writeRow(row)
        mysql.insert(item)
if __name__ == "__main__":
    #firstRow = ['问题', '问题URL', '回答者', '回答者URL', '获赞', '详细信息URL']
    #wirte = CSV('zhihu.csv',firstRow)
    row = ['question','qurl','autuor','aurl','zan','detail']
    mysql = Mysql('zhihu',row,7)
    mysql.create_table()
    zhihu = zhiHu()
    zhihu.getUrl()

</strong><em>这里说明一点,from store_csv import CSV,from store_mysql import Mysql这两个是自己写的两个类,实现方法可以参考python简单操作csv文件小例和老哥Mr_Cxypython对Mysql数据库的操作小例这两篇文章,这里可以不添加cookie信息</em>
<strong>

selector = etree.HTML(html.content.decode('utf-8'))

通过对html.content进行解码,输出结果正常。

3.scrapy版本思路

yield scrapy.Request(url,callback=self.parse)

</strong><em>代码中提到的URL指的是下一页的URL,通过获取下一页信息调用parse函数抓取信息</em><strong>

下一页

这里使用了parse_item进行页面数据的提取(编写爬虫规则时,避免使用 parse 作为回调函数。 由于 CrawlSpider
使用 parse方法来实现其逻辑,如果覆盖了 parse方法,crawl spider 将会运行失败。)
关于CrawlSpider
的详细使用方法可以参考官方文档或者参考相关的代码和文章

4.数据信息(mysql和csv)

mysql zhihu.csv

总结

通过对比动态网页(ajax)和静态网页,在思想上差别不是很大(参数+分页),在解析方式动态的一般都是通过解析json来获取数据,静态则通过Beautifulsoup、xpath、正则去获取数据。
爬爬爬,下一个网站走起!

上一篇 下一篇

猜你喜欢

热点阅读