美文网首页
爬虫小记

爬虫小记

作者: 浪里_个郎 | 来源:发表于2020-04-01 15:48 被阅读0次

    内容包含:
    1,简略描述爬虫代码编写流程
    2,对于动态页面的爬取
    代码:
    https://github.com/zackLangChina/JavaCrawler

    一,爬虫代码编写流程

    1.1,发送HTTP request,获取HTTP response

    java:

        //使用OKHTTP发送request
        private static OkHttpClient client = new OkHttpClient();
        //返回html
        public static String get(String url) throws IOException {
            Request request = new Request.Builder()
                    .url(url)
                    .build();
    
            try (Response response = client.newCall(request).execute()) {
                return response.body().string();
            }
        }
    

    python:

    import requests
    
    #返回HTTP
    def getHTTPText(url):
        try:
            r = requests.get(url, timeout=10)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return r.text
        except:
            return ""
    

    1.2,在HTTP源码中搜索我们需要的元素

    CSS选择器、正则表达式匹配等方式查找
    java:

            //JSOUP解析
            Document document = Jsoup.parse(mHtml);
            Elements elements = document
                    .select("ul[class=feed-list-hits feed-list-index]")
                    .select("li[class=feed-row-wide J_feed_za feed-haojia]");
            for (Element element : elements) {
              ...
    

    python:

        //BeautifulSoup解析
        soup = BeautifulSoup(html, "html.parser")
        for li in soup.find_all(name="li", attrs={"class": "av-gallery-item"}):
    

    1.3,数据本地存储

    写CSV文件或写数据库

    当然,实际应用中会遇见很多问题:
    1,需要模拟按键等操作
    2,需要获取异步数据XHR并解析
    3,反爬机制

    二,静态页面和Ajax页面

    某一网址为 https://www.xxx.com/xxx?id=a&page=b&value=c 这样的网址,显性地将属性添加到主体的后面,那么对于这类网站,我们只需要修改request的url就能抓取到静态页面中的数据。
    对于Ajax的网页,网页刷新时,浏览器的Url并不会改变,而是通过发送一个request,获取了页面上一部分数据的刷新。ajax请求可能获得的是一部分页面的html代码,也可能是json格式的表单数据,我们可以在F12的preview或response里查看具体获得的数据类型,做不同的处理。

    2.1构建ajax页面的request

    以企查查举例。进入某个公司信息的页面,查看知识产权-专利信息,我们点击专利信息的翻页按钮,浏览器地址栏的url是不变的。打开F12,查看XHR信息,可以在Headers中看到request和response:


    XHR

    同时,在XHR的Response中可以看到新打开页面的HTML代码:


    ajax返回的页面代码
    我们还可以在Headers的最下面看到我们点击翻页时,request中带了哪些信息:
    请求时发送的信息

    这个图里我们可以看出,request带的主要信息有:
    unique / companyname / p / tab / box
    还有一些空参数:zlpublicationyear / zlipclist / zlkindcode / zllegalstatus

    对比了两个公司的XHR Headers:

    公司A:
    https://www.qcc.com/company_getinfos?unique=06396efe66551d4ac07ee8cb41b0e325&companyname=%E5%B9%BF%E4%B8%9C%E5%B9%BF%E4%BF%A1%E9%80%9A%E4%BF%A1%E6%9C%8D%E5%8A%A1%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8&p=2&tab=assets&box=zhuanli&zlpublicationyear=&zlipclist=&zlkindcode=&zllegalstatus=
    公司B:
    https://www.qcc.com/company_getinfos?unique=70991e4c3796c47dd9d9e634fec5def0&companyname=%E6%B5%99%E6%B1%9F%E5%8D%8E%E4%BB%AA%E7%94%B5%E5%AD%90%E8%82%A1%E4%BB%BD%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8&p=2&tab=assets&box=zhuanli&zlpublicationyear=&zlipclist=&zlkindcode=&zllegalstatus=
    

    可以通过参数的差异和页面信息分析出参数的含义:
    unique:企查查中某个公司的主页地址。如打开某个公司,地址栏是:
    https://www.qcc.com/firm_06396efe66551d4ac07ee8cb41b0e325.html
    06396efe66551d4ac07ee8cb41b0e325就和上面的unique=06396efe66551d4ac07ee8cb41b0e325值对应上了
    companyname:公司名称
    p:网页的页数,于是只要更改该键的值,我们就可以实现对每一页进行爬取
    tab:标签页,代表了知识产权页面
    box:作为不同的表格的标识。这里的zhuanli特指专利信息表格

    那么,我们就可以给出爬取企查查企业专利信息的代码流程了:
    1,获取企业名称列表
    2,进入企业页面
    3,从静态页面中获取专利信息总共的页数,如下图,可以通过遍历div class="m-b"中的元素得知总共有多少页
    4,构建request,获取response中的页面信息


    步骤3,获取专利信息页码

    用代码说明一些细节:

        private final String url = "https://www.qcc.com/company_getinfos";
        private final String KEY_UNIQUE = "unique";
        private final String KEY_COMPANY = "companyname";
        private final String KEY_P = "p";
        private final String KEY_TAB = "tab";
        private final String KEY_BOX = "box";
        private final String TAB_ASSERTS = "assets";
        private final String BOX_ZHUANLI = "zhuanli";
        private final String COOKIE = "xxx" //浏览器的cookie,QCC不登录不能查询
        //通过HttpUrl.Builder构建参数键值对,其实就是帮你拼接字符串
        HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
        urlBuilder.addQueryParameter(KEY_UNIQUE,"06396efe66551d4ac07ee8cb41b0e325");
        urlBuilder.addQueryParameter(KEY_COMPANY,"广东广信通信服务有限公司");
        urlBuilder.addQueryParameter(KEY_P,"1");
        urlBuilder.addQueryParameter(KEY_TAB,TAB_ASSERTS);
        urlBuilder.addQueryParameter(KEY_BOX,BOX_ZHUANLI);
    
        //发送请求,注意需要补充请求头
        Request request = new Request.Builder()
            .url(urlBuilder.build())
            .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36")
            .addHeader("Cookie", cookie)
            .addHeader("accept","text/html, */*; q=0.01")
            .addHeader("accept-encoding","gzip, deflate, br")
            .addHeader("accept-language","zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7")
            .addHeader("referer","https://www.qcc.com/firm_06396efe66551d4ac07ee8cb41b0e325.html")
            .addHeader("sec-fetch-dest","empty")
            .addHeader("sec-fetch-mode","cors")
            .addHeader("sec-fetch-site","same-origin")
            .addHeader("x-requested-with","XMLHttpRequest")
            .build();
    
        Response response = client.newCall(request).execute();
        //返回html
        return response.body().string();
    

    如果不把header加全一些,会被禁止访问:


    企查查反爬

    但即便这样,reponse得到的是一堆乱码,不知道具体是什么。但至少说明这样是可以用来获取ajax动态网页数据的,达到了学习的目的。


    response返回

    相关文章

      网友评论

          本文标题:爬虫小记

          本文链接:https://www.haomeiwen.com/subject/zmvouhtx.html