python-爬虫技能升级记录

====== python-爬虫技能升级记录 ======

===== (一)感知爬虫及爬取流程 =====
<code>
从简单存取一个页面到 爬取到大量的定量数据,对技术要求更高,以百度百科数据爬取为入门练手项目.历时一个月,经历很多问题.

爬取流程:分析目标网页、得到url、拿url抓取、解析抓到的页面、存取数据和解析出的url、去重 继续迭代抓。

通过扩大关键词范围、从页面提取更多相关url源来覆盖更多可抓页,提升抓取数据量。
chrome浏览器F12是个好工具,把网页解析过程看的一目了然。
练好正则表达式,用好用熟python的各个爬虫工具库。
爬虫这个活,很锻炼分析he提取信息能力。

提高抓取速度,速度,速度.

</code>
===== (二)那些问题 =====

<code>
2.1 沟通上的问题:爬和存最终是要百度百科某个词条的完整页面,我误以为是要进一步析取页面某个部分的结果,浪费了点时间去练没用到的正则表达式;
2.2 爬取过程中发现问题的能力:
    爬取的前2天,数据从大量快速增长 到突然降到很小,爬取很突然变慢,结果是缺数据库索引 数据查询操作变慢拖累了爬取速度,
    --------> 需要随时观察数据量变化及时把握住趋势 提早解决问题;

    每天评估抓取速度he目标数据量差距,提前开源--找新的关键词或者新的抓取方式抓取源头;

2.3 爬虫背景知识欠缺:http_status, 200 301,302,代理,并发

2.4 数据上的问题
   1) 遇到多义词的特殊页面 : https://baike.baidu.com/item/%E6%88%BF%E4%BA%A7 ;
   2) 拼接关键词错误 : https://baike.baidu.com/item/https://baike.baidu.com/error.html ;
   3) 不存在的页面处理问题: https://baike.baidu.com/error.html
   
</code>

==== [0001] url解析问题 ====结果

<code>
抓数据过程中,要从抓来的网页内容 提取url和所需关键字 ,用 urllib.parse.urlparse提取 路径,urllib.parse.unquote解码
比如 提取到url https://baike.baidu.com/item/%E5%86%8D%E7%94%9F%E4%B9%8B%E7%8E%8B%E6%9C%9D --> /item/再生之王朝

</code>

==== [0002] mysql crash了 ====
<code>
[问题]:数据 20G时,db crash,200w的数据 int类型的字段上 index 重建 花了 1.5小时,追查无果
[解决]:是内存耗尽,导致mysql的数据库索引文件损坏。
mysql修复命令:
myisamchk  --force --update-state --sort_buffer_size=2G  /data/mysql/data/baidu/baidu_baike
</code>
==== [0003] 302是啥?allow_redirects的作用 ====

<code>
302是一种重定向状态码,表明,要取得最终结果需要进一步请求.

301   (永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302   (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303   (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304   (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305   (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307   (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

url = 'https://pan.baidu.com/s/1c0rjnbi'
tml = requests.get(url, headers=headers, allow_redirects=False)
return html.headers['Location']
allow_redirects=False的意义为拒绝默认的301/302重定向从而可以通过html.headers[‘Location’]拿到重定向的URL

https://baike.baidu.com/view/38072.html
urllib.error.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop

</code>

==== [0004] 多thread的段错误问题 ====

起多个抓取thread ,运行一段时间报段错误 抓取程序崩溃--> mysql-connector.x86_64的包问题,换 mysql-connector_2.1.4 或者 pymysql后解决。

<code>[115686.825855] python3.5[112899]: segfault at 50 ip 00007f506bc70ba1 sp 00007f506a823f40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7f506bc1a000+3b9000]
[116821.355924] python3.5[122287]: segfault at 50 ip 00007fb8aedfeba1 sp 00007fb8ad9b1f40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7fb8aeda8000+3b9000]
[117432.277293] python3.5[124563]: segfault at 50 ip 00007f3e80cebba1 sp 00007f3e7f89ef40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7f3e80c95000+3b9000]
[117682.160350] python3.5[129646]: segfault at 50 ip 00007feea0327ba1 sp 00007fee9ef1af40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7feea02d1000+3b9000]
[117891.158342] python3.5[633]: segfault at 50 ip 00007ff5d0581ba1 sp 00007ff5cf174f40 error 4 in _mysql_connector.cpython-35m-x86_64-linux-gnu.so[7ff5d052b000+3b9000]
</code>


==== [0005] XHR是啥? ====
XMLHttpRequest,动态异步请求。
[[https://www.cnblogs.com/syfwhu/p/6116323.html| XHR简介 ]]
[[https://blog.csdn.net/zhiruchen/article/details/50983371|观察数据-分析-构造请求-结果]]
[[https://blog.csdn.net/zwq912318834/article/details/78364710|XHR-寻找参数来源]]


[[https://blog.jamespan.me/2016/02/28/mysql-select-from-update|mysql-select-from-update]]

==== [0006] 遇到cookie了 ====

<code>
url = "https://baike.baidu.com/wikiui/api/getcertifyinfo?lemma={0}".format("%E5%8C%97%E4%BA%AC%E5%85%AB%E5%8F%8B%E7%A7%91%E6%8A%80%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8")
    headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8',
            'X-Requested-With': 'XMLHttpRequest',
        }
    
    session = requests.Session()
    respn = session.post(url, verify = False, headers = headers, allow_redirects=False)

    # https://baike.qixin.com/?eid=ea2b58fa-0b3f-440c-9076-d8735fdcc882&token=6018b5609a2c2ccf4cb8e4915ffcc4a7
    sec_url = eval(respn.text)['data']['iframe'].replace('/','/')
    print('--sec_url--:' , sec_url)

    cookie_jar = RequestsCookieJar()
    cookie = respn.cookies.get_dict()
    for k, v in cookie.items():
        cookie_jar.set(k, v, domain="baidu.com")
    print('cookie---', cookie, ' --',str(cookie_jar))
    

    rtext2 = session.post(sec_url, verify = False, headers = headers, cookies=cookie_jar, allow_redirects=False).text

    print('rtext2--: ' , rtext2)
</code>

[[https://blog.csdn.net/hpulfc/article/details/80084398| python--获取和设置cookie]]

==== [0007] 再探requests库 ====

python的变量引用原理, requests的post和get, requests的session的文档和用途;

==== [0098] 爬取速度可能慢的因素 ====

1. 多线程处理到同样任务,造成浪费;

2. 涉及到db操作的, 抓取队列长度和 db队列处理长度的最佳匹配;


==== [0099] 爬虫的调试 ====
<code>
 python的开发技能上:

1. 一定要了解整个抓取处理的流程;
2. 每个流程的环节打日志看消耗的时长;
3. 对目标数据量和程序的处理能力有清晰的感知;
4. 别瞎猜, 打日志看.

Linux系统有关:
 1. 段错误出现后及时看dmesg ,能看到是mysql连接器的包报出异常;


</code>
===== (三)欠缺之处和待提升的技能 =====
欠缺之处:

梳理问题能力要锻炼he提升, 进入状态慢,在开发进度把控上欠缺节奏感。


爬虫技术待提升技能:
并发, 异步, cookie,登录,验证码


----

[[https://github.com/davisking/dlib/issues/1104|段错误-参考资料 (the most important rule when writing multithreaded applications is that you can't have two threads modifying the same thing at the same time)]]

原文地址:https://www.cnblogs.com/mousean/p/9909392.html