http爬虫浅谈

Theday

因兴趣写了一点点爬虫,浅谈爬虫的一些简单操作吧。

1. 第一步先确定要爬取的url

无论接口还好,还是html文本也好,获取其他的数据,先通过抓包工具确定好要爬取的url地址

2. 使用 Python 构造请求,然后开始爬取数据

对于互联网上的站点,接口等,模拟人类操作构造响应的请求,设置对应的请求头,来获取想要的数据

3. 对于第二步爬取到的数据,进行清洗
  • 数据爬取到了,解析接口,解析xml文本,html文本数据,找到想要的数据,清洗不相关的数据,也是为了构造结构化数据吧。
  • 常用到 xpath,正则等提取文本内容。
  • 也可再次深度爬取,进行第一步操作
4. 数据持久化(数据保存到本地,[文件,数据库])

第三步爬取到想要的数据,构造好结构化数据就可以进行持久化存储了。文件或者数据库都可

题外:

再就是爬虫异常、分布式爬虫和反爬

  • 爬虫异常:一般来说是反爬引起的异常,对方站点更新了反爬技术。
  • 分布式爬虫:多机器的同时爬取同一站点上的数据,快速爬取站点数据
  • 反爬:应对站点的一些反爬技术:验证码,ip,代码混淆等。

Web crawler: 网络爬虫

  • 网络爬虫模拟人类使用浏览器浏览、操作页面的行为,对互联网的站点进行操作
  • 网络爬虫获取到一个页面后,会分析出页面里的所有 URI,沿着这些 URI路径递归的遍历所有页面,因此被称为爬虫(Web crawler)、蜘蛛(Spider)、网络机器人(spiderbot)
案例一:根据关键词爬取新浪新闻数据,抓取新闻【标题,来源,发布时间,内容】
第一步:确定要爬取的url: https://search.sina.com.cn/?q=%E6%98%A5%E8%8A%82&range=all&c=news&sort=time

爬取url

python构造请求
    def __send_page_req(self, page_num: int = 1):
        """
        发起请求
        :return:
        """
        search_url = self.__init_search_url(page_num)
        response = requests.get(search_url)
        response = Selector(response=response)
        return response

    def __init_search_url(self, page: int = 1):
        """
        构造请求数据
        :param page:
        :return:
        """
        params = {
            'q': self.search_keyword,
            'range': "all",
            'c': 'news',
            'sort': "time",
            'page': page
        }
        str_params = urllib.parse.urlencode(params)
        return self.search_url + '?' + str_params
数据清洗
    def parse_page_req(self, page_num: int = 1):
       pass
完整代码:(根据关键词爬取日期在2020-12-01 后的所有新浪新闻数据)
import requests
from scrapy.selector import Selector
import urllib.parse
import datetime
import re

class SinaNewsSpider:
    """
    新浪新闻搜索
    """
    search_url = 'https://search.sina.com.cn/?{params}'
    spider_source = 'sina'
    title_compile = re.compile('<a.*?>([\s\S]*?)</a>')
    article_min_date = '2020-12-01 00:00:00'  # 新闻的最早时间

    def __init__(self, search_keyword: str):
        self.search_keyword = search_keyword

    def go(self):
        page_num = 1
        while True:
            news_data, min_date = self.parse_page_req(page_num)
            [self.__save(item) for item in self.parse_data(news_data)]
            if min_date > self.article_min_date:
                page_num += 1
            else:
                break

    def __save(self, data):
        """
        数据存储
        :param data:
        :return:
        """
        print(data)
        pass

    def parse_data(self, news_data):
        """
        数据解析
        :param news_data:
        :return:
        """
        for news in news_data:

            content = self.__get_content(news['detail_url'])
            if content is None:
                print('error:', news)
            else:
                item = {}
                item['content'] = content
                item['source'] = 'sina'
                item['keyword'] = self.search_keyword
                item['news_url'] = news['detail_url']
                item['insert_time'] = str(datetime.datetime.today())
                item['title'] = news['title']
                item['release_time'] = news['release_time']
                item['author'] = news['author']
                yield item

    def __get_content(self, url):
        response = requests.get(url)
        response = Selector(text=response.content.decode('utf-8'))
        content = response.xpath('//div[@id="article"]').extract_first()
        content_artibody = response.xpath('//div[@id="artibody"]').extract_first()
        content_section = response.xpath('//section[@class="art_pic_card art_content"]').extract_first()
        return content or content_artibody or content_section

    def parse_page_req(self, page_num: int = 1):
        """
        解析翻页请求
        :param response:
        :return:
        """
        response = self.__send_page_req(page_num)
        news_list = response.xpath('//div[@id="result"]/div[@class="box-result clearfix"]')
        news_data = []

        for news in news_list:
            item = {}
            title = news.xpath(".//h2/a").extract_first()
            item['title'] = self.title_compile.findall(title)[0]
            item['detail_url'] = news.xpath(".//h2/a/@href").extract_first()
            source_time_str = news.xpath(".//h2/span/text()").extract_first().strip()
            item['author'], item['release_time'] = source_time_str.split(" ", maxsplit=1)
            news_data.append(item)
        return news_data, min(map(lambda x: item['release_time'], news_data))

    def __send_page_req(self, page_num: int = 1):
        """
        发起请求
        :return:
        """
        search_url = self.__init_search_url(page_num)
        response = requests.get(search_url)
        response = Selector(response=response)
        return response

    def __init_search_url(self, page: int = 1):
        """
        构造请求数据
        :param page:
        :return:
        """
        params = {
            'q': self.search_keyword,
            'range': "all",
            'c': 'news',
            'sort': "time",
            'page': page
        }
        str_params = urllib.parse.urlencode(params)
        return self.search_url.format(params=str_params)


sina = SinaNewsSpider("春节")
news_data = sina.go()
python 还是一个非常不错的工具。
阅读 916

singwa服务端学习小组
singwa服务端学习小组 技术共享平台
6 声望
0 粉丝
0 条评论
6 声望
0 粉丝
文章目录
宣传栏